ASP.NET Core 实现微服务 - Consul 配置中心

news2025/1/11 18:22:40

这一次我们继续介绍微服务相关组件配置中心的使用方法。本来打算介绍下携程开源的重型配置中心框架 apollo 但是体系实在是太过于庞大,还是让我爱不起来。因为前面我们已经介绍了使用Consul 做为服务注册发现的组件
,那么干脆继续使用 Consul 来作为配置中心吧。Consul 除了服务注册发现功能,还有个 Key/Value 存储的功能,我们把本地的 appsettings.json 文件的内容搬到 Key/Value 上就可以实现配置中心了。

把服务的配置迁移至 Consul

让我们来改造一下前面系列文章里的 member_center 项目,把配置文件都迁移到 consul 上面去。
 


在 consul 控制台点击 “Key/Value” 菜单,点击 “create” 按钮新建一个 Key/Value 对象。
 


Key/Value 支持按文件夹分类,当我们的 Key 以 / 结尾的时候,consul 会认为这是一个文件夹。
我们在这里输入 “member_center/” 在创建文件夹。
 


在创建的文件夹目录下继续点击 “create” 按钮。
 


在 key 文本框里输入 “confing.json” 。
在 Value 文本框内把原来 appsettings.json 文件的全部内容复制粘贴进去。

{
  "consul_server": "http://192.168.18.164:8500"
}

把原来 appsettings.json 文件的内容全部删除,只输入一行 consul_server 的配置,用来指示 consul 服务的地址。

Install-Package Winton.Extensions.Configuration.Consul 

在 member_center 项目上通过nuget安装 Winton.Extensions.Configuration.Consul 这个组件。

    public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureAppConfiguration((ctx,cfg)=> {
                        var localconfig = new ConfigurationBuilder()
                                    .SetBasePath(Directory.GetCurrentDirectory())
                                    .AddJsonFile("appsettings.json").AddEnvironmentVariables().Build();
                        var consul_server = localconfig["consul_server"];

                        cfg.AddConsul("member_center/config.json",op=> {
                            op.ConsulConfigurationOptions = cco =>
                            {
                                cco.Address = new Uri(consul_server);
                            };
                            op.ReloadOnChange = true;
                        });
                    });
                    webBuilder.ConfigureKestrel(options =>
                    {
                        options.ListenAnyIP(6002);
                    });
                    webBuilder.UseStartup<Startup>();
                });

在 program 文件的 CreateHostBuilder 方法内配置使用 Consul 做为配置的提供源。首先从本地读取 consul_server 的地址。通过 AddConsul 方法指示需要从 consul 读取的配置文件的路径。完成以上操作后我们的服务已经可以读取到 Consul 存储的配置了。

   [ApiController]
    [Route("[controller]")]
    public class ConsulController : ControllerBase
    {
        IConfiguration _configuration;
        public ConsulController(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        [HttpGet("getConfig")]
        public string GetConfig(string key)
        {
            return _configuration[key];
        }
    }

我们新建一个GetConfig方法来演示下能否读取到配置。
直接在 Controller 构造函数注入 IConfiguration 来读取配置,这跟我们普通本地配置的读取方式完全一致。

http://localhost:6002/consul/getconfig?key=hotreload_test


 


在浏览器上访问一下这个action对应的url,并且指定一个key=hotreload_test,可以看到输出的结果跟我们在 consul 上配置的值是一致的。
 


 


修改一下 consul 上面的配置值,重新读取一下这个配置,可以看到新的值已经被读取到了,证明我们的热更新也可以运行了。

把 Ocelot 网关的配置迁移至 Consul

上面我们演示了如何把普通服务的配置迁移至 consul,下面演示下如何把 Ocelot 的配置迁移到 Consul 上。
Ocelot 网站其实也就是一个 webapi 项目,本质上跟上面的服务没啥区别。我们根据上面的演示,其实可以很容易的把 Ocelot 项目的配置迁移到 Consul 上。那么为什么需要单独说一下 Ocelot 网关的迁移呢?
本来 Ocelot 的路由配置需要把下游服务的地址跟端口在配置文件里写死,那样的话,我们的 Consul 服务注册发现就没有意义了,我们的下游服务都是可能动态变化的。所以我们需要让 Ocelot 结合 Consul 的服务注册发现功能来把下游服务器的配置动态化。这就导致 Ocelot 项目跟 Consul 的融合会比一般的服务复杂一点。

Install-Package Ocelot.Provider.Consul

首先我们在项目上使用 nuget 安装 Ocelot.Provider.Consul 这个组件。

{
  "consul_server": "http://192.168.18.164:8500"
}

同样我们需要在本地的 appsettings.json 文件内指定 consul_server 的地址。再把 routes.json 文件的内容全部迁移至 consul 的 key/value 上去,这个不在赘述。
 


注意,这里不是简单的复制粘贴 routes.json 文件的内容。
我们需要把原来的 DownstreamHostAndPorts 配置全部删掉,替换成服务名,并且指定负载均衡的算法。

"ServierName" : "hotel_base",
"LoadBalanceOptions": {
    "Type": "LeastConnection"
}

在 "GlobalConfiguration" 节点指定 "ServiceDiscoveryProvider":

"ServiceDiscoveryProvider": {
    "Scheme": "http",
    "Host": "192.168.18.164",
    "Prot": 8500,
    "Type": "Consul"
}

ServiceDiscoveryProvider 节点指示了使用 Consul 做为服务发现的组件及Consul服务的基本信息。

        public static void Main(string[] args)
        {
            new WebHostBuilder()
              .UseKestrel()
              .UseContentRoot(Directory.GetCurrentDirectory())
              .ConfigureAppConfiguration((hostingContext, config) =>
              {
                  var localconfig = new ConfigurationBuilder()
                                .SetBasePath(Directory.GetCurrentDirectory())
                                .AddJsonFile("appsettings.json").AddEnvironmentVariables().Build();
                  var consul_server = localconfig["consul_server"];

                  config.AddConsul("gateway/routes.json", op => {
                      op.ConsulConfigurationOptions = cco =>
                      {
                          cco.Address = new Uri(consul_server);
                      };
                      op.ReloadOnChange = true;
                  });

                  config.AddEnvironmentVariables();
              })
              .ConfigureServices(s => {
                  s.AddOcelot()
                  .AddConsul()
                  .AddTransientDefinedAggregator<HotelDetailInfoForMobileAggregator>();
              })
              .ConfigureLogging((hostingContext, logging) =>
              {
                  logging.AddConsole();
               })
              .UseIISIntegration()
              .Configure(app =>
              {
                  app.UseOcelot().Wait();
              })
              .Build()
              .Run();
        }

我们改造一下 program 文件的 main 方法,在ConfigureAppConfiguration的配置方法内首先获取 consul_server 的地址。通过AddConsul方法指示获取配置文件的地址。
以上跟服务的配置迁移都是一致的,除了以上操作使用 Consul 作为 ServiceDiscoveryProvider 还需要在 ConfigureServices 方法的配置函数内指定 consul 相关的依赖注入。

   s.AddOcelot()
    .AddConsul()


我们运行起来所有的服务跟网关项目,访问一下 /api/hotel 这个路由,可以看到请求被正确的转发到了对应的服务上了。

总结

以上我们演示了如何把服务的配置迁移到 Consul 的 Key/Value 对象上并且实现了配置的读取及热更新。演示了 Ocelot 网关的路由配置如何迁移到 Consul 的 Key/Value 对象上并且不再写死下游服务的配置信息,而是使用 Consul 的服务发现能力动态获取下游服务的配置信息。通过以上演示我们可以发现整个过程还是非常简单易用的,虽然 Consul 做为配置中心功能相对于 apollo 等功能还不够强大,比如没有版本管理,用户权限,审计等功能,但是对于一些小的微服务项目也已经足够了。如果你的微服务体系中使用了 Consul 做为服务注册发现的组件,那么可以直接使用 Consul 来做为配置中心,这样在能够获得基本的配置中心能力同时也省去了再部署一套单独的配置中心的繁琐操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2275038.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tdengine数据库使用java连接

1 首先给你的项目添加依赖 <dependency> <groupId>com.taosdata.jdbc</groupId> <artifactId>taos-jdbcdriver</artifactId> <version>3.4.0</version> <!-- 表示依赖不会传递 --> </dependency> 注意&am…

深入学习RabbitMQ的Direct Exchange(直连交换机)

RabbitMQ作为一种高性能的消息中间件&#xff0c;在分布式系统中扮演着重要角色。它提供了多种消息传递模式&#xff0c;其中Direct Exchange&#xff08;直连交换机&#xff09;是最基础且常用的一种。本文将深入介绍Direct Exchange的原理、应用场景、配置方法以及实践案例&a…

51单片机——串口通信(重点)

1、通信 通信的方式可以分为多种&#xff0c;按照数据传送方式可分为串行通信和并行通信&#xff1b; 按照通信的数据同步方式&#xff0c;可分为异步通信和同步通信&#xff1b; 按照数据的传输方向又可分为单工、半双工和全双工通信 1.1 通信速率 衡量通信性能的一个非常…

本地手集博客id“升级”在线抓取——简陋版——(2024年终总结1.1)

我之前每每发布笔记都用csv纯文本记录&#xff0c;一个机缘巧得文章列表api实现在线整理自已的文章阅读量数据。 (笔记模板由python脚本于2025年01月10日 18:48:25创建&#xff0c;本篇笔记适合喜欢钻牛角尖的coder翻阅) 【学习的细节是欢悦的历程】 Python官网&#xff1a;htt…

高等数学学习笔记 ☞ 洛必达法则与泰勒公式

1. 洛必达法则 1. 型与型未定式&#xff08;洛必达法则&#xff09; &#xff08;1&#xff09;型&#xff1a;若函数同时满足以下条件&#xff1a; &#xff08;2&#xff09;型&#xff1a;若函数同时满足以下条件&#xff1a; ①&#xff1a;当时&…

Qt官方下载地址

1. 最新版本 Qt官方最新版本下载地址&#xff1a;https://www.qt.io/download-qt-installer 当前最新版本Qt6.8.* 如下图&#xff1a; 2. 历史版本 如果你要下载历史版本安装工具或者源码编译方式安装&#xff0c;请转至此链接进行下载&#xff1a;https://download.qt.i…

怎么用NodeJS脚本对接TTS播报音响

怎么用NodeJS脚本对接TTS播报音响呢&#xff1f; 本文描述了使用NodeJS脚本调用HTTP接口&#xff0c;对接TTS播报音响&#xff0c;。 可选用产品&#xff1a;可根据实际场景需求&#xff0c;选择对应的规格 序号设备名称厂商1智能语音音柱|10W统软物联2智能语音壁挂音箱|款式…

计算机存储之图解机械硬盘

问&#xff1a;机械硬盘是如何工作的&#xff1f; 答&#xff1a;请看VCR 一、机械硬盘物理结构 1.1、盘片(platter) 视频中银白色的圆盘称为盘片&#xff0c;二进制数据就是存储在盘片上&#xff0c;盘片解剖后如下图所示&#xff1a; 一圈一圈的同心圆称为磁道&#xff08;…

HTML前端从零开始

第一天 HTML部分 什么是HTML HTML&#xff08;Hypertext Markup Language&#xff09;超文本标记语言。HTML是万维网的基石。 超&#xff1a; 超字第一层意义是指最重要的标签&#xff0c;超链接标签 超越文本的意思 HTML的发展历程 HTML1990年出现&#xff0c;web之父…

moviepy 将mp4视频文件提取音频mp3 - python 实现

DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” -------------------------------------------------------------…

【Leetcode-移动零】利用将非零元素移动至数组前解决移动零问题(剪枝优化)

题目描述 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例1 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] 示例2 输入: nums [0] 输出…

浅析大语言模型安全和隐私保护国内外标准和政策

过去两年&#xff0c;大模型技术已经普及并逐步渗透到各行各业&#xff0c;2025年注定是大模型应用井喷式发展的一年&#xff0c;AI在快速发展的同时&#xff0c;其带来的安全风险也逐渐凸显。人工智能系统的安全性和隐私保护已经成为社会关注的重点。 附下载&#xff1a;600多…

第21篇 基于ARM A9处理器用汇编语言实现中断<三>

Q&#xff1a;怎样编写ARM A9处理器汇编语言代码配置按键端口产生中断&#xff1f; A&#xff1a;使用Intel Monitor Program创建中断程序时&#xff0c;Linker Section Presets下拉菜单中需选择Exceptions。主程序在.vectors代码段为ARM处理器设置异常向量表&#xff0c;在…

直流无刷电机控制(FOC):电流模式

目录 概述 1 系统框架结构 1.1 硬件模块介绍 1.2 硬件实物图 1.3 引脚接口定义 2 代码实现 2.1 软件架构 2.2 电流检测函数 3 电流环功能实现 3.1 代码实现 3.2 测试代码实现 4 测试 概述 本文主要介绍基于DengFOC的库函数&#xff0c;实现直流无刷电机控制&#x…

(四)结合代码初步理解帧缓存(Frame Buffer)概念

帧缓存&#xff08;Framebuffer&#xff09;是图形渲染管线中的一个非常重要的概念&#xff0c;它用于存储渲染过程中产生的像素数据&#xff0c;并最终输出到显示器上。简单来说&#xff0c;帧缓存就是计算机图形中的“临时画布”&#xff0c;它储存渲染操作生成的图像数据&am…

Linux离线部署ELK

文章目录 前期准备开始安装安装elastic search安装logstash安装kibana 配置ELK配置ElasticSearch配置logstash配置kibana 启动ELK启动命令启动测试 设置ELK策略创建ILM策略将ILM策略与日志index关联查看索引是否被ILM策略管理 前期准备 ELK包含三部分软件 ElasticSearch用作搜…

LabVIEW数据库管理系统

LabVIEW数据库管理系统&#xff08;DBMS&#xff09;是一种集成了数据库技术与数据采集、控制系统的解决方案。通过LabVIEW的强大图形化编程环境&#xff0c;结合数据库的高效数据存储与管理能力&#xff0c;开发人员可以实现高效的数据交互、存储、查询、更新和报告生成。LabV…

微服务实现高并发 秒杀系统,前后端实现

一、前端实现 前端项目初始化 首先&#xff0c;我们需要创建一个新的 Vue 3 项目。你可以使用 Vue CLI 来快速搭建项目。 安装 Vue CLI&#xff08;如果尚未安装&#xff09; bash npm install -g vue/cli 创建 Vue 项目 bash vue create seckill-frontend cd seckill-f…

Http请求响应——请求

Http概述 Http协议&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;&#xff0c;是一种用于传输网页数据的协议&#xff0c;规定了浏览器和服务器之间进行数据传输的规则&#xff0c;简单说来就是客户端与服务器端数据交互的数据格式。 客户端…

Vue3 + Vite + Electron + Ts 项目快速创建

一、创建 Vue 项目 1. 创建项目 pnpm create vite 2. 安装依赖 cd excel-electron pnpm install 3. 运行项目 pnpm dev 二、添加 Electron 1. 安装 electron pnpm add electron -D 2. 修改 package.json 添加入口 js 和执行命令。 {"main": "dist-ele…