首页 > 其他分享 >consul:啥?我被优化没了?AgileConfig+Yarp替代Ocelot+Consul实现服务发现和自动网关配置

consul:啥?我被优化没了?AgileConfig+Yarp替代Ocelot+Consul实现服务发现和自动网关配置

时间:2024-04-11 12:25:18浏览次数:21  
标签:网关 discoveryService consul AgileConfig yarp item var new Consul

现在软件就业环境不景气,各行各业都忙着裁员优化。作为一个小开发,咱也不能光等着别人来优化咱,也得想办法优化下自己。就拿手头上的工作来说吧,我发现我的微服务应用里,既有AgileConfig这个配置中心组件,又有一个Consul 服务发现组件。本来吧他俩也没啥事,各干个的。但是,我在操作AgileConfig的时候发现了一个事image
然后我又一百度发现了这个AgileConfig 1.6.0 发布 - 支持服务注册与发现 - Agile.Zhou - 博客园 (cnblogs.com),有点意思。稍微一思索,我们现在的微服务解决方案里网关用的ocelot+consul 作为HTTP api网关,同时 还是用了 yarp做 grpc的网关,明显可以看出来有一套多余的网关在这里。基于目前的情况,我是一直想优化掉 ocelot+consul这个组合。改用 agileConfig+yarp,奈何前期对微服务机制不是很熟悉,有堆坑要填。现在看到agileconfig的服务列表,又勾起了我这个优化的想法。说干就干,我理想的目标是可以直接从agileconfig上获取到所有注册的服务,然后用代码来动态给yarp添加代理配置。这样既可以优化掉一个consul服务,又可以免去每次服务部署时繁琐的网关配置。

首先第一个任务就是解决yarp如何用代码实现动态配置的问题。bing 里搜索 yarp 动态配置 ,优先看博客园的博主发的文章,事实上我也就只看了这一篇Welcome to YARP - 2.2 配置功能 - 配置提供者(Configuration Providers) - coding-y - 博客园 (cnblogs.com) 。完美,问题解决。下面就是代码时间。

通过上面两篇文章我们知道,agileconfig会提供一个IDiscoveryService 接口来供程序获取注册的服务信息。同时 yarp也提供了从内存中提供配置的 InMemoryConfigProvider ,那我们只需要在agileconfig 注册之后 通过 IDisconverService接口 获取所有已注册服务,然后再让yarp应用上内存中的配置即可实现服务注册后自动配置代理的需求。

下面我们动动手指头 按下 ctrl c ,ctrl v实现如下代码:代码不具备通用性 需要进一步优化 建议已给出。

using AgileConfig.Client;
using AgileConfig.Client.RegisterCenter;
using Newtonsoft.Json.Linq;

using Yarp.ReverseProxy.Configuration;
using Yarp.ReverseProxy.Transforms;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class AgileConfigProxyConfigProviderExtend
    {
        const string NotProxyStr = "notProxy";
        const string TransformsStr = "Transforms";
        static readonly ILogger _Logger = LoggerFactory.Create(b => { }).CreateLogger("AgileConfigProxyConfigProviderExtend");
        public static RouteConfig[] GetRoutes(this IDiscoveryService discoveryService)
        {
            var routes = new List<RouteConfig>();
            foreach (var item in discoveryService.Services)
            {
                if (item.MetaData.Any(r=>r.Equals(NotProxyStr, StringComparison.OrdinalIgnoreCase)))
                {
                    continue;
                }
                var route = new RouteConfig
                {
                    RouteId = item.ServiceId,
                    ClusterId = item.ServiceName,
                    Match = new RouteMatch
                    {
                        Path = $"/{item.ServiceName}/{{**all}}"
                    }
                };
                //.WithTransformPathRouteValues(pattern: new PathString("/{**all}"))
                try
                {
                    var transformStr = item.MetaData.FirstOrDefault(r => r.StartsWith(TransformsStr));
                    if (transformStr is not null)
                    {
                        var jobj = JObject.Parse(transformStr.Split(':')[1]);
                        foreach (var k in jobj)
                        {
                            route.WithTransform(d => d.Add(k.Key, k.Value?.ToString() ?? ""));
                        }
                    }
                }
                catch (Exception e)
                {
                    _Logger.LogError(e,"生成路由【转换】配置时出错");
                }

                routes.Add(route);
                _Logger.LogTrace("添加路由{RouteId}", route.RouteId);
            }
            return routes.ToArray();
        }
        public static ClusterConfig[] GetClusters(this IDiscoveryService discoveryService)
        {
            var clusters = new List<ClusterConfig>();
            var proxyServices = discoveryService.Services
                                    .Where(r => !r.MetaData.Any(r => r.Equals(NotProxyStr, StringComparison.OrdinalIgnoreCase)))
                                    .GroupBy(p => p.ServiceName);

            foreach (var item in proxyServices)
            {
                var destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase);
                foreach (var service in item)
                {
                    destinations.Add(service.ServiceId, new DestinationConfig() {
                        Address=service.AsHttpHost()
                    });
                }

                clusters.Add(new ClusterConfig
                {
                    ClusterId = item.Key,
                    Destinations = destinations
                });
            }

            return clusters.ToArray();
        }
        //可以再加一个重载 支持传入一个委托 来自定义构造配置。
        public static IReverseProxyBuilder LoadFromAgileConfigByInMemoryConfigProvider(this IReverseProxyBuilder builder, ConfigClient client)
        {
            var discoveryService = client.DiscoveryService();
            discoveryService ??= new DiscoveryService(client, LoggerFactory.Create(b => b.SetMinimumLevel(LogLevel.Information)));

            var configProvider = new InMemoryConfigProvider(discoveryService.GetRoutes(), discoveryService.GetClusters());

            builder.Services.AddSingleton(configProvider);
            builder.Services.AddSingleton<IProxyConfigProvider>(configProvider);

            discoveryService.ReLoaded += () =>
            {
                configProvider.Update(discoveryService.GetRoutes(), discoveryService.GetClusters());
            };
            return builder;
        }
    }
}

现在只需要调用如下代码,即可给原有的yarp服务加上自动生成代理配置的功能了。

builder.Services.AddReverseProxy()//添加ReverseProxy相关服务到DI

.LoadFromAgileConfigByInMemoryConfigProvider((ConfigClient)client);

注意:注册AgileConfig时候请使用 UseAgileConfig()方法注册。Addxxx方法会导致无法获取到agileConfig上的已注册服务对信息。
代码已传gitee:https://gitee.com/dotnetfans/yarp-auto-proxy.-agile-config
同时也个给agileConfig 提交了合并请求。

标签:网关,discoveryService,consul,AgileConfig,yarp,item,var,new,Consul
From: https://www.cnblogs.com/chinasoft/p/18128791

相关文章

  • consul:啥?我被优化没了?AgileConfig+Yarp替代Ocelot+Consul实现服务发现和自动网关配置
    现在软件就业环境不景气,各行各业都忙着裁员优化。作为一个小开发,咱也不能光等着别人来优化咱,也得想办法优化下自己。就拿手头上的工作来说吧,我发现我的微服务应用里,既有AgileConfig这个日志组件,又有一个Consul服务发现组件。本来吧他俩也没啥事,各干个的。但是,我在操作AgileConfig......
  • 支持onvif协议的摄像机如何加入视频网关
    配置onvif设备的用户名和密码打开浏览器,输入摄像头的IP地址,登录摄像头的web页面。 在web页面上,找到并点击“设置”选项,然后依次选择“网络”->“高级配置”->“集成协议”。 把“启用ONVIF”勾选,启用ONVIF协议。点击“添加”,并输入设定的ONVIF用户名和密码,用户类型选“管......
  • TSINGSEE青犀边缘计算AI智能分析网关V4客流统计算法的配置步骤及使用
    TSINGSEE青犀AI智能分析网关V4内置了近40种AI算法模型,支持对接入的视频图像进行人、车、物、行为、烟火等实时检测分析,上报识别结果,并能进行语音告警播放。硬件支持RTSP、GB28181协议、以及厂家私有协议接入,可兼容市面上常见的厂家品牌设备,可兼容IPC、网络音柱等。同时也支持智能......
  • TSINGSEE青犀边缘计算AI智能分析网关V4客流统计算法的配置步骤及使用
    TSINGSEE青犀AI智能分析网关V4内置了近40种AI算法模型,支持对接入的视频图像进行人、车、物、行为、烟火等实时检测分析,上报识别结果,并能进行语音告警播放。硬件支持RTSP、GB28181协议、以及厂家私有协议接入,可兼容市面上常见的厂家品牌设备,可兼容IPC、网络音柱等。同时也支持智......
  • 关于新书《云原生网关Traefik》的一点解读
    Hellofolks,我是Luga,今天我们继续来聊一下云原生生态领域相关的技术-云原生网关Traefik。    相信通过之前的文章分享,大家对Traefik或许已有了初步的认识。不过,光说不练终归徒劳,因此,本文我将重点解读 #国内首作、#全网唯一一本体系化介绍Traefik的最新书籍:《云......
  • 边缘智能网关:企业数字化转型的助推器-天拓四方
    一、企业背景随着信息技术的飞速发展,企业对于数据处理和通信的需求日益增长。特别是在工业4.0、智能制造等领域,企业面临着海量的数据采集、实时分析、远程监控等挑战。传统的中心化数据处理模式已难以满足这些需求,企业需要寻求一种更加高效、灵活的数据处理方式。某专注于智......
  • 数控机床采集网关助力企业实现智能化生产-天拓四方
    随着工业4.0时代的到来,智能制造成为制造业转型升级的重要方向。数控机床作为制造业的核心设备,其数据采集与监控对于提升生产效率、优化生产流程具有重要意义。本案例将介绍数控机床采集网关的应用,通过该网关实现数控机床数据的实时采集、传输与分析,助力企业实现智能化生产。案......
  • PLC通过Modbus转Profinet网关连接压力计的配置方法
    由于现场控制器无法正常连接压力计,咨询了解后我们通过使用Modbus转Profinet网关把连接压力计和控制顺利连接并通讯上,实现Modbus协议与Profinet协议之间的数据转换和传输,使得压力计能够无缝集成到基于Profinet的工业自动化系统中。Modbus转Profinet网关接压力计的配置方法主要包......
  • modbus转profinet网关接温度传感器方案
    Modbus转Profinet网关用于实现Modbus协议和Profinet协议之间的数据转换和传输。Modbus转Profinet网关接温度传感器的方案主要涉及将Modbus协议的温度传感器数据转换为Profinet协议,以便与工业自动化系统中的其他设备进行通信和数据交换。以下是实现此方案的基本步骤:首先确定温度......
  • 如何解决Modbus转Profinet网关的常见问题
    Profinet转Modbus网关(XD-MDPN100)如同Modbus设备和Profinet设备的桥梁,Profinet转Modbus网关(XD-MDPN100)可以实现Modbus设备和Profinet设备的数据双向转换和传输,是两种不同通信协议之间的桥梁,在进行Profinet转Modbus网关调试时可能会遇到一些常见问题。以下是一些解决Modbus转Profi......