Ocelot之服务发现
继上篇 Ocellot 做负载均衡之后,本篇将记录 Ocelot + Consul 试验如何做服务发现和服务注册。
服务发现和服务注册的背景知识,一搜满街都是。
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。在此,我还是写下自己对这个术语的理解吧。上篇虽然对多个服务节点做了负载均衡,但如果其中一个节点挂掉了,我们访问时会现一次成功一次失败,这在实际生产环境中是绝对不允许的,也失去了负载均衡原来的意义。
那么我们必须保证子节点服务,有某些服务挂掉了,只要其中有一个或一个以上的节点服务是还健康活着,那整个服务就还是继续工作工作。Ocelot网关是不能感知到,其下节点服务有哪些是好的,所以需要借助某种工具,去主动监听其下节点服务的状态,这就是服务发现。Ocelot早已兼容Consul这种服务发现工具。
下面,我们先在linux机上安装一下Consul,具体如下:
$ wget https://releases.hashicorp.com/consul/1.4.4/consul_1.4.4_linux_amd64.zip
$ sudo apt-get install unzip
$ ls
$ unzip consul_1.4.4_linux_amd64.zip
$ sudo mv consul /usr/local/bin/consul
以上命令,在官网下了个包,然后解压了一下,里面只有一个 consul文件,把文件移到了/usr/local/bin/consul。
然后,就真的没有然后了,Consul 安装完毕!
试下 $ consul
看到这个,安装就是成功的了。
体验一下: consul agent -dev
看一下成员: consul members
然后在浏览器上试访问一下:192.168.1.23
体验完了,就把它移除吧,dev是拿来试的
$ consul leave
下面我们对代码配置,做一点小修改。修改之前,简单说一下代码结构,一个网关,两个API
所有项目的appsetting.json都设置一下,各自读自定义IP和Port,
public static IWebHost BuildWebHost(string[] args) { return WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseUrls(new ConfigurationBuilder().SetBasePath(System.IO.Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build()["ApplicationUrl"]).Build(); }
{ "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "ApplicationUrl": "http://192.168.1.232:5011" }
修改一下 lanchSettings.json, 取消通过浏览器启动
{ "profiles": { "Dashboard": { "commandName": "Project", "launchBrowser": false, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, "applicationUrl": "http://localhost:5012/" } } }
解决方案启动项目设置如下:
apigateway项目的ocelot.json的配置:定义了下游两个服务节点,开启了服务发现,配置了consul的连接IP和POrt
{ "UseServiceDiscovery": true, // do not use Consul service discovery "DownstreamPathTemplate": "/master/{url}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "192.168.1.232", "Port": "5011" }, { "Host": "192.168.1.232", "Port": "5012" } ], "ServiceName": "MasterService", "LoadBalancerOptions": { "Type": "RoundRobin" }, "UpstreamPathTemplate": "/master/{url}", "UpstreamHttpMethod": [ "Get", "Post" ], "RateLimitOptions": { "ClientWhitelist": [ "admin" ], // 白名单 "EnableRateLimiting": true, // 是否启用限流 "Period": "1m", // 统计时间段:1s, 5m, 1h, 1d "PeriodTimespan": 15, // 多少秒之后客户端可以重试 "Limit": 10 // 在统计时间段内允许的最大请求数量 }, "QoSOptions": { "ExceptionsAllowedBeforeBreaking": 2, // 允许多少个异常请求 "DurationOfBreak": 5000, // 熔断的时间,单位为秒 "TimeoutValue": 3000 // 如果下游请求的处理时间超过多少则视如该请求超时 }, "ReRoutesCaseSensitive": false // non case sensitive }
"GlobalConfiguration": { //"BaseUrl": "https://api.mybusiness.com" "ServiceDiscoveryProvider": { "Host": "192.168.1.23", // Consul Service IP "Port": 8500 // Consul Service Port },
分别对两个api加一个健康检查入口:
[HttpGet("/master/health")] public IActionResult Heathle() { return Ok(); }
至此,网关和2个API的准备工作完毕。跑起来!
下面,通过文件方式,向consul注册服务,在linux上创建一个service.json, 随便找个地方放一下
{ "encrypt": "Wd7HAMtcgg5RQ2hZhHE9xw==", "services": [ { "id": "api1", "name": "MasterService", "tags": [ "ApiService" ], "address": "192.168.1.232", "port": 5011, "checks": [ { "id": "ApiServiceA_Check", "name": "ApiServiceA_Check", "http": "http://192.168.1.232:5011/health", "interval": "10s", "tls_skip_verify": false, "method": "GET", "timeout": "1s" } ] }, { "id": "api2", "name": "MasterService", "tags": [ "ApiService" ], "address": "192.168.1.232", "port": 5012, "checks": [ { "id": "ApiServiceB_Check", "name": "ApiServiceB_Check", "http": "http://192.168.1.232:5012/health", "interval": "10s", "tls_skip_verify": false, "method": "GET", "timeout": "1s" } ] } ] }
运行下面的命令:
consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul -node=consul-1 -client=0.0.0.0 -bind=0.0.0.0 -datacenter=dc1 -config-dir=/consul/testservices &
参数说明:
-server:服务器模式
-ui:能webui展示
-bootstrap-expect:server为1时即选择server集群leader
-data-dir:consul状态存储文件地址
-config-dir: 刚才放service.json的位置
-node:指定结点名
-advertise:本地ip地址
-client:指定可访问这个服务结点的ip
& : run as background server
再访问一下 8500
可以看到,两个节点服务在健康地存在。
访问一下服务,可以看到节点在来会切变
下面是实验最关键的一步,让其中一个节点挂掉,看看服务还能不能继续,我把 api1,关掉,后面再访问,一直都是
试验完毕。
总结:
1.一开始是也是跟着https://www.cnblogs.com/edisonchou/p/9124985.html来学习的,但因为我没有那么多虚拟机,就没办法按他那方式来做,但他那种才是 贴近生产环境的,具有更高的参考价值。
2.我是奔着试验的目的,所以参考https://www.cnblogs.com/alan-lin/p/9126155.html来做,基本都是一样的,惟一不同只是consul的安装环境而已。
3.关于微服务,我的观点:
微服务是将一个系统按业务拆分成多个服务,然后以http-json的方式或者rpc的方式,被外部访问或者服务间通信;
微服务是需要有单点登录的;
这是微服务最基本的要素;
但作为一个程序员,真的不要低估自己现在做的东西,自己写的代码,有一天你做的项目做的系统将会一步步成长壮大,养活很多很多人
所以微服务应该还要有健康检测,要有集群,要高可用,要有服务发现....因为有了这样的观点,所以我后面不断地在学习微服务的知识。
4.微服务框架下的代码,将不会再是重量级的,框架性很强的代码,因为代码拆分成了多个项目解决方案,这个解决方案必须层次非常清楚,一般不会超过10个project,5个左右的project总会让人看着舒服。
