NLog 是我们在 .NET 领域使用非常广泛的日志组件。它默认使用 xml 来维护它的配置。最近有几个同学问我当使用 AgileConfig 的时候如何配置 NLog 。因为 AgileConfig 不支持集成 xml 格式的配置。其实 NLog 是支持从 appsettings.json / IConfiguration 读取配置的,那么肯定跟我们的 AgileConfig 集合是没有问题的。以下介绍下 NLog 如何跟 AgileConfig 进行集成,以及支持动态化的配置。
使用 AgileConfig 配置 NLog
NLog 默认的配置是通过 xml 来配置的。现在我们的 .NET 程序大多数都是通过 appsettings.json 来配置的。NLog 提供了从 appsettings.json / IConfiguration 读取配置的的扩展。既然支持 IConfiguration 读取那么跟我们的 AgileConfig 起来就非常简单了。
[Read More]
.net 中 gc 的模式
垃圾回收(GC)是托管语言必备的技术之一。GC 的性能是影响托管语言性能的关键。我们的 .NET 既能写桌面程序 (WINFROM , WPF) 又能写 web 程序 (ASP.NET CORE),甚至还能写移动端程序。。。不同使用场景的程序对 GC 的风格也有不同的要求,比如桌面程序更注重界面的响应速度,web 程序注重的是吞吐量。有幸的是 CLR 为我们提供了2种不同的 GC 模式与风格。 Workstation GC 工作站模式被设计为客户端(桌面)程序使用,或者某些只有1个核心的机器使用。工作站模式下 GC 的回收频次会加快,但是每一次 GC 造成的停顿很短暂。工作站模式的垃圾回收直接发生在触发垃圾回收的用户线程上。所以垃圾回收线程需要跟其他用户线程去竞争 CPU 时间。工作站模式下只会分配一个 GC 堆,在工作站模式下 GC 分配的内存会更少。 Server GC 服务器模式适合大型的服务端应用,比如 ASP.NET Core 程序。服务器模式下 GC 的回收会尽量的延迟,从而减少停顿。为了获得更高的吞吐量与性能,程序会分配更多的内存。服务器模式下 CLR 根据 CPU 核心数量来分配 GC 堆的数量。同时为每个 GC 堆分配一个专用线程来执行回收,并且这个线程的优先级为 THREAD_PRIORITY_HIGHEST ,所以在与普通线程竞争的时候更容易获得...
[Read More]
Agileconfig 1.6.0 发布 支持服务注册与发现
大家好,好久没有输出博文了,一是因为比较忙,另外一个原因是最近主要的精力是在给 AgileConfig 添加一个新的功能:服务注册与发现。 先说说为什么会添加这个功能。我自己的项目是用 Consul 来做为服务注册发现组件的。自从我上线了 AgileConfig 做为配置中心后,我就很少去 Consul 观察服务的在线状态了,因为 AgileConfig 客户端列表已经在一定程度上能代表服务的状态了。服务注册发现与配置中心其实本质上都是解决了一类问题,那就是配置的动态化,所以大家会看到业界著名的组件很多都是同时实现这2个功能的,如 Consul,Nacos 等。所以我想干脆把这个功能给加上吧,这样可以省去部署一个组件。 当然也有同学说我不务正业,不去好好搞配置中心去搞什么服务注册发现。但是我还是做了。。。 不过大家放心 AgileConfig 的主业还是在配置中心上,服务注册发现只是附赠的小菜,可以用也可以不用,决定权完全在你。在实现上我也是对两个功能是完全解耦的。也就是说这2个功能都是互不影响独立运行的。唯一有交集的一个地方是,如果配置中心的客户端的 websocket 通道建立成功的时候,服务的心跳会借用这个通道。 ✨✨✨Github地址:https://github.com/dotnetcore/AgileConfig 开源不易,欢迎star✨✨✨ 什么是服务注册与发现 首先先让我们回顾下服务注册发现的概念。 在实施微服务之后,我们的调用都变成了服务间的调用。服务间调用需要知道IP、端口等信息。再没有微服务之前,我们的调用信息一般都是写死在调用方的配置文件里(当然这话不绝对,有些公司会把这些信息写到数据库等公共的地方,以方便维护)。又由于业务的复杂,每个服务可能依赖N个其他服务,如果某个服务的IP,端口等信息发生变更,那么所有依赖该服务的服务的配置文件都要去修改,这样显然太麻烦了。有些服务为了负载是有个多个实例的,而且可能是随时会调整实例的数量。如果每次调整实例数量都要去修改其他服务的配置并重启那太麻烦了。 为了解决这个问题,业界就有了服务注册发现组件。 假设我们有服务A需要调用服务B,并且有服务注册发现组件R。整个大致流程将变成大概3部: 服务B启动向服务R注册自己的信息 服务A从服务R拉取服务B的信息 服务A调用服务B 有了服务注册发现组件之后,当修改A服务信息的时候再也不用去修改其他相关服务了。 参考我的另外一篇:.Net Core with 微服务 - Consul 注册中心 使用服务注册与发现 使用服务注册与发现功能需要更新服务端与客户端至 1.6.0 及以上版本。 启动服务端 服务端更新至 latest 镜像或 v-1.6.0 以上的镜像。 使用 docker...
[Read More]
Dapr 01
安装 Dapr CLI
```
powershell -Command “iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex”
[Read More]
Memorycache 如何清除全部缓存?
最近有个需求需要定时清理服务器上所有的缓存。本来以为很简单的调用一下 MemoryCache.Clear 方法就完事了。谁知道 MemoryCache 类以及 IMemoryCache 扩展方法都没有 Clear 方法。这可给难住了,于是想找到所有的 Keys 来一个个 Remove ,谁知道居然也没有获取所有 Key 的方法。于是研究了一下 ,找到一些方法,下面介绍两个方法:
自定义 CacheWrapper 包装类
MemoryCache 构造 Entry 的时候支持传入 CancellationChangeToken 对象,当 CancellationChangeToken.Cancel 触发的时候会自动使该对象过期。那么我们只要对 MemoryCache 类包装一下很容易实现一个自己的 Cache 类。
```
public class CacheWrapper
{
private readonly IMemoryCache _memoryCache;
private CancellationTokenSource _resetCacheToken = new();
[Read More]