庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

时间:2021-07-23 00:39:15

庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



一、简介

       在第七篇文章《庐山真面目之七微服务架构Consul集群、Ocelot网关集群和IdentityServer4版本实现》中,我们已经探讨了如何搭建基于Windows 环境的Consul服务集群、Ocelot网关集群和认证的微服务架构。我们是不是这样就算是完成了微服务架构的搭建了吗?当然没有了,生产环境中肯定不会在Windows系统下搭建这些,以前只不过是测试的环境。从今天开始我们将要微服务架构搬到Linux环境中去,并且是基于Docker来搭建的?今天这篇文章会很长,大家要有耐性。



    1、说明

           在看这篇文章之前,大家还是要有些准备的。比如:会操作Linux系统,会使用Docker,基本操作要会,对Net5.0也要所有了解,也就是对跨平台开发有所了解,还要有一些镜像文件,比如:nginx,consul等等,还有其他的一些基础,大家都要熟悉,这些东西没有办法写在这里了。在此特别声明:如果是高手的话,这些东西相对于您来说,肯定是微不足道,请您口下留德,再者说,这些文章是为零基础的人写的,不要抬杠了,如果有高见,也希望不灵赐教。特别说明,这里的所有代码都经过测试,所以大家可以放心使用。



    2、开发环境

          
以下就是开发环境,不用多说,都很简单,一看就知道。

         (1)、开发工具:Visual
Studio 2019

         (2)、开发语言:C#

         (3)、开发平台:Net 5.0和Net Core 3.1,跨平台。

         (4)、服务注册:Consul集群,服务注册、发现中心

         (5)、服务治理:Ocelot集群,负载均衡、服务治理

         (6)、网关服务:Nginx 服务组件,一个负载Consul服务,一个负载Ocelot网关。

         (7)、操作系统:Linux(CentOS7)。

         (8)、鉴权授权:IdentityServer4



    3、我们的目标

          今天我们的目标是,在Linux系统上搭建基于Docker来实现Consul集群、Ocelot集群和IdentityServer4鉴权、授权的微服务架构。这个任务比较艰巨,篇幅一定很长,因为包含的内容有点多。当然这个肯定不是最终版本,我们还会继续演化下去。

           目标框架如图:

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

二、搭建Consul服务的集群。

   



           庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现


        Consul 用 Golang 实现,因此具有天然可移植性(支持 Linux、windows 和 Mac OS X ),它的安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。

        在这里我们仅仅对Consul集群做简单的介绍,具体的详情可以自己去网上学习。Consul服务在Cluster集群上的每一个节点都运行一个Agent代理,这个Agent代理可以使用Server服务器或者Client客户端模式。Client客户端负责到Server服务器端的高效通信,相对为无状态的。 Server服务器端负责:包括选举领导节点,维护Cluster集群的状态,对所有的查询做出响应,跨数据中心的通信等等。

        Agent代理可以运行在Server服务器模式或者Client客户模式,每个数据中心至少有一个Agent代理运行在server服务器模式,一般建议是3或者5个Server。部署单个Server是非常不好的,因为在失败场景中出现数据丢失是不可避免的。我们今天要3个服务器端和1个客户端来完成我们今天的架构任务。



        名词解释:

        A、Client :Consul 的 Client模式,就是客户端模式。是
Consul 节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到 Server,本身不具有持久化数据的功能。

        B、Server :Consul 的 Server 模式,表明这个
Consul 是个 Server ,这种模式下,功能和 Client 都一样,唯一不同的是,它会把所有的数据持久化的本地,这样遇到故障,信息是可以被保留的。

        C、Server-Leader:是所有服务器们的老大,它和其它
Server 不一样的一点是,它需要负责同步注册的信息给其它的 Server ,同时也要负责各个节点的健康监测。

        D、Raft:Server 节点之间的数据一致性保证协议使用的是 raft,而
Zookeeper 用的
PAXOS,ETCD采用的也是Raft服务发现协议,Consul 采用 http 和 DNS 协议,ETCD 只支持 http 。

        E、服务注册:Consul 支持两种方式实现服务注册,一种是通过 Consul 的服务注册API(Http协议),由服务自己调用 API 实现注册;另一种方式是通过
JSON 格式的配置文件实现注册,将需要注册的服务以
JSON 格式的配置文件给出。Consul 官方建议使用第二种方式。



    Consul文档:https://www.consul.io/docs

    Consul官网:https://www.consul.io



       我们开始在Linux环境中基于Docker来搭建我们的Consul服务集群。



       1、在Linux系统中,先查看我们是否有Consul的镜像,如果没有就赶紧拉去吧。


               命令:#docker images,我这里没有,我把环境清空了,所以我要重新拉取。

      庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

               命令:#docker pull
consul

      庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



       2、开始启动服务实例,3个服务器端实例,一个客户端实例。

              
Client
客户端,不会存储数据。Server服务器端可以固化数据,3个服务器端,实现 Raft算法,选举出一个Leader。初始化需要3个Server服务器节点,选出Leader 服务器节点负责数据同步。如果只有一个Server 节点,集群会失败。

       

              参数解释:

                   consul agent:命令头,必须要有。

                   -server表示要启动服务器代理(agent)模式。Consul
Agent节点的运行模式有两种,Server模式和Client模式。其区别就是Server模式数据可以持久化到本地,而Client模式不可以。

                   -uiconsul运行后,会提供一个http://127.0.0.1:8500/ui/的网站,里面存储了Consul
Agent各个节点以及注册的服务等相关信息,即数据中心的网页形式体现。这个参数代表是否创建这个网站,这个参数与这个数据中心网站有关。

                   -bind本机的IP地址,集群内其他代理服务器可以通过这个IP来访问这台电脑的consul代理服务器。

                   -bootstrap-expect:是集群启动条件,指当服务器端模式(Server模式)的代理达到这个数目后,才开始运行。

                   -data-dir是存放数据中心数据的目录,该目录必须是稳定的,系统重启后也继续存在的。

                   -config-dir:是存放数据中心日志的目录,该目录必须是稳定的,系统重启后也继续存在的。

                   -datacenter:当前Consul的中心数据的名称,默认是dc1。

                   -node节点在集群中的名称,在一个集群中必须是唯一的,默认是该节点的主机名(代表一个机器)。

                   -client本地IP地址,这里使用
0.0.0.0 ,就表示这个服务器所有IP都可以,即当这台电脑有俩IP,192.168.1.100和192.168.1.111,那么通过这俩IP都可以访问到这台机器的consul代理服务器。

                   -join表示当前的服务器节点或者是客户端节点要加入集群的服务器,后面跟要加入的服务器的具体IP地址。



              安装完成后,Agent就可以启动了,我们开始搭建我们Consul集群了。



                (1)、启动
Consul-Server-Leader
主节点。

                         命令:# docker run -d
--name=masternode --restart=always -e
'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt":true}' -p 8300:8300
-p 8301:8301 -p 8301:8301/udp -p 8302:8302/udp -p 8302:8302 -p 8400:8400 -p
8500:8500 -p 8600:8600 -h masternode consul agent -server -bind=0.0.0.0
-bootstrap-expect=3 -node=masternode -data-dir=/tmp/data-dir -client 0.0.0.0
-ui

 1     docker run -d --name=masternode --restart=always \
2 -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt":true}'\
3 -p 8300:8300\
4 -p 8301:8301\
5 -p 8301:8301/udp\
6 -p 8302:8302/udp\
7 -p 8302:8302\
8 -p 8400:8400\
9 -p 8500:8500\
10 -p 8600:8600\
11 -h masternode\
12 consul agent -server -bind=0.0.0.0 -bootstrap-expect=3 -node=masternode\
13 -data-dir=/tmp/data-dir -client 0.0.0.0 -ui
14
15 Consul的地址:http://192.168.127.141:8500/

          启动:

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                         效果:

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



               (2)、创建Server-
Follower
,Consul集群中的第一个追随者

                         命令:# docker
run -d --name=followernode --restart=always -e
'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt":true}' -p 9300:8300
-p 9301:8301 -p 9301:8301/udp -p 9302:8302/udp -p 9302:8302 -p 9400:8400 -p
9500:8500 -p 9600:8600 -h followernode consul agent -server -bind=0.0.0.0
-join=192.168.127.141 -node-id=$(uuidgen | awk '{print tolower($0)}')
-node=followernode -data-dir=/tmp/data-dir -client 0.0.0.0 -ui

 1     docker run -d --name=followernode --restart=always\
2 -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt":true}'\
3 -p 9300:8300\
4 -p 9301:8301\
5 -p 9301:8301/udp\
6 -p 9302:8302/udp\
7 -p 9302:8302\
8 -p 9400:8400\
9 -p 9500:8500\
10 -p 9600:8600\
11 -h followernode\
12 consul agent -server -bind=0.0.0.0 -join=192.168.127.141\
13 -node-id=$(uuidgen | awk '{print tolower($0)}') -node=followernode\
14 -data-dir=/tmp/data-dir -client 0.0.0.0 -ui
15
16
17 Consul的地址:http://192.168.127.141:9500/

          启动:

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                         效果:

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                    

               (3)、创建Server-
Follower
,Consul集群中的第二个追随者

                         命令:#docker
run -d --name=followernode2 --restart=always -e
'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt":true}' -p 10300:8300
-p 10301:8301 -p 10301:8301/udp -p 10302:8302/udp -p 10302:8302 -p 10400:8400
-p 10500:8500 -p 10600:8600 -h followernode2 consul agent -server -bind=0.0.0.0
-join=192.168.127.141 -node-id=$(uuidgen | awk '{print tolower($0)}')
-node=followernode2 -data-dir=/tmp/data-dir -client 0.0.0.0 -ui

 1     docker run -d --name=followernode2 --restart=always\
2 -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt":true}'\
3 -p 10300:8300\
4 -p 10301:8301\
5 -p 10301:8301/udp\
6 -p 10302:8302/udp\
7 -p 10302:8302\
8 -p 10400:8400\
9 -p 10500:8500\
10 -p 10600:8600\
11 -h followernode2\
12 consul agent -server -bind=0.0.0.0\
13 -join=192.168.127.141 -node-id=$(uuidgen | awk '{print tolower($0)}') -node=followernode2\
14 -data-dir=/tmp/data-dir -client 0.0.0.0 -ui
15
16 Consul的地址:http://192.168.127.141:10500/

          启动:

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                         效果:

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

        
      
(4)、创建Consul-Client ,Consul集群中的客户端。

                         命令:#docker
run -d --name=clientNode --restart=always -e
'CONSUL_LOCAL_CONFIG={"leave_on_terminate":true}' -p 11300:8300 -p
11301:8301 -p 11301:8301/udp -p 11302:8302/udp -p 11302:8302 -p 11400:8400 -p
11500:8500 -p 11600:8600 -h clientNode consul agent -bind=0.0.0.0
-retry-join=192.168.127.141 -node-id=$(uuidgen | awk '{print tolower($0)}')
-node=clientNode -data-dir=/tmp/data-dir -client 0.0.0.0 -ui

 1     docker run -d --name=clientnode --restart=always\
2 -e 'CONSUL_LOCAL_CONFIG={"leave_on_terminate":true}'\
3 -p 11300:8300\
4 -p 11301:8301\
5 -p 11301:8301/udp\
6 -p 11302:8302/udp\
7 -p 11302:8302\
8 -p 11400:8400\
9 -p 11500:8500\
10 -p 11600:8600\
11 -h clientnode\
12 consul agent -bind=0.0.0.0 -retry-join=192.168.127.141\
13 -node-id=$(uuidgen | awk '{print tolower($0)}') -node=clientnode\
14 -data-dir=/tmp/data-dir -client 0.0.0.0 -ui
15
16 Consul的网站:http://192.168.127.141:11500/

          启动:

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                         效果:

      庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



       3、验证3个服务器端和一个客户端是否安装成功。


               执行这些命令,都要切换到Consul所在的目录。切记。

               (1)、执行命令查看容器实例

                           命令:#docker ps
–a

             庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



               (2)、查看Consul成员列表,三个服务器端实例,一个客户端实例。

              
命令:#docker exec -t clientnode consul members

                  
庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

               3
个server,1个client,状态是:alive,说明集群创建成功。



         
(3)、我们在看看服务器角色的分配是否合适?一主二从,则表示运行成功。

               
命令:#docker exec -t masternode consul operator raft
list-peers

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                (4)、我们也可以通过浏览器访问以下地址,验证Consul服务是否安装成功。

             
             第一主服务器: http://192.168.127.141:8500

                           第二从服务器: http://192.168.127.141:9500

                           第三从服务器: http://192.168.127.141:10500

                           Consul客户端: http://192.168.127.141:11500

                           能看到如下截图,也可以说明成功。我只截一个图了,其他都类似。

              庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

三、搭建微服务测试项目。

          我们要想搭建微服务架构,第一步,我们当然要搭建我们自己的测试项目了,代码都很简单,主要是为了突出各个开源技术点。这是基础中的基础,没有这一步,其他的都是空中楼阁,没有说服力了。废话少说,我们开始吧。

    

        1、建立测试项目,并编写各个项目的所需代码。


                (1)、PatrickLiu.MicroService.Client(ASP.NET CORE
MVC),客户端项目。


                          该项目模仿客户端程序,当然可以是你愿意的任何客户端程序,别抬杠,我这里只是一个简单的MVC项目,通过地址访问微服务。

                庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                           样例代码:

                

 1 using System;
2 using System.Collections.Generic;
3 using System.Net.Http;
4 using Microsoft.AspNetCore.Mvc;
5 using Microsoft.Extensions.Logging;
6 using PatrickLiu.MicroService.Interfaces;
7 using PatrickLiu.MicroService.Models;
8
9 namespace PatrickLiu.MicroService.Client.Controllers
10 {
11 public class HomeController : Controller
12 {
13 private readonly ILogger<HomeController> _logger;
14 private readonly IUserService _userService;
15
16 /// <summary>
17 /// 初始化该类型的新实例。
18 /// </summary>
19 /// <param name="logger">注入日志对象。</param>
20 /// <param name="userService">注入用户服务对象。</param>
21 public HomeController(ILogger<HomeController> logger, IUserService userService)
22 {
23 _logger = logger;
24 _userService = userService;
25 }
26
27 /// <summary>
28 /// 首页。
29 /// </summary>
30 /// <returns></returns>
31 public IActionResult Index()
32 {
33
34 #region 通过 Ocelot 集群网关访问服务实例,追加访问 Token,切记,我这里没写。
35
36 string url = "http://192.168.127.141:8083/gate/users/all";
37
38 #endregion
39
40 string content = InvokeAPI(url);
41 this.ViewBag.Users = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<User>>(content);
42 Console.WriteLine($"This is {url} Invoke.");
43
44 #endregion
45
46 return View();
47 }
48
49
50 /// <summary>
51 ///
52 /// </summary>
53 /// <param name="url"></param>
54 /// <returns></returns>
55 public static string InvokeAPI(string url)
56 {
57 using (HttpClient client = new HttpClient())
58 {
59 HttpRequestMessage message = new HttpRequestMessage();
60 message.Method = HttpMethod.Get;
61 message.RequestUri = new Uri(url);
62 var result = client.SendAsync(message).Result;
63 string conent = result.Content.ReadAsStringAsync().Result;
64 return conent;
65 }
66 }
67 }
68 }

      (2)、PatrickLiu.MicroService.Interfaces(NET CORE 类库),定义服务接口,面向接口编程嘛,代码很简单,因为重点不是它。

                        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                           样例代码:                           

 1 using PatrickLiu.MicroService.Models;
2 using System.Collections.Generic;
3
4 namespace PatrickLiu.MicroService.Interfaces
5 {
6 /// <summary>
7 /// 用户服务的接口定义。
8 /// </summary>
9 public interface IUserService
10 {
11 /// <summary>
12 /// 查找指定主键的用户实例对象。
13 /// </summary>
14 /// <param name="id">用户的主键。</param>
15 /// <returns>返回查找到的用户实例对象。</returns>
16 User FindUser(int id);
17
18 /// <summary>
19 /// 获取所有用户的实例集合。
20 /// </summary>
21 /// <returns>返回所有的用户实例。</returns>
22 IEnumerable<User> UserAll();
23 }
24 }

      (3)、PatrickLiu.MicroService.Models(NET CORE 类库),定义实例类型,主要用于数据传递,代码很简单,因为重点不是它。

           庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现 
         

                           样例代码:

 1 using System;
2
3 namespace PatrickLiu.MicroService.Models
4 {
5 /// <summary>
6 /// 用户模型。
7 /// </summary>
8 public class User
9 {
10 /// <summary>
11 /// 获取或者设置用户主键。
12 /// </summary>
13 public int ID { get; set; }
14
15 /// <summary>
16 /// 获取或者设置用户姓名。
17 /// </summary>
18 public string Name { get; set; }
19
20 /// <summary>
21 /// 获取或者设置用户账号名称。
22 /// </summary>
23 public string Account { get; set; }
24
25 /// <summary>
26 /// 获取或者设置用户密码。
27 /// </summary>
28 public string Password { get; set; }
29
30 /// <summary>
31 /// 获取或者设置用户的电子邮箱地址。
32 /// </summary>
33 public string Email { get; set; }
34
35 /// <summary>
36 /// 获取或者设置用户角色。
37 /// </summary>
38 public string Role { get; set; }
39
40 /// <summary>
41 /// 获取或者设置用户的登录时间。
42 /// </summary>
43 public DateTime LoginTime { get; set; }
44 }
45 }

      (4)、PatrickLiu.MicroService.Services(NET CORE 类库),定义服务实现,我们有了接口,然后基于接口实现具体的服务,代码很简单,因为重点不是它。

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

               样例代码:

                            

 1 using PatrickLiu.MicroService.Interfaces;
2 using PatrickLiu.MicroService.Models;
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6
7 namespace PatrickLiu.MicroService.Services
8 {
9 /// <summary>
10 /// 实现用户服务接口的实现类型。
11 /// </summary>
12 public class UserService : IUserService
13 {
14 private IList<User> dataList;
15
16 /// <summary>
17 /// 初始化类型的实例
18 /// </summary>
19 public UserService()
20 {
21 dataList = new List<User>()
22 { new User {ID=1,Name="黄飞鸿",Account="HuangFeiHong",Password="HuangFeiHong123456",Email="huangFeiHong@sina.com", Role="Admin", LoginTime=DateTime.Now },
23 new User {ID=2,Name="洪熙官",Account="HongXiGuan",Password="HongXiGuan54667",Email="HongXiGuan@sina.com", Role="Admin", LoginTime=DateTime.Now.AddDays(-5) },
24 new User {ID=3,Name="方世玉",Account="FangShiYu",Password="FangShiYu112233",Email="fangShiYu@163.com", Role="Admin", LoginTime=DateTime.Now.AddDays(-30) },
25 new User {ID=4,Name="苗翠花",Account="MiaoCuiHua",Password="MiaoCuiHua887766",Email="miaoCuiHua@sohu.com", Role="Admin", LoginTime=DateTime.Now.AddDays(-90) },
26 new User {ID=5,Name="严咏春",Account="YanYongChun",Password="YanYongChun09392",Email="yanYongChun@263.com", Role="Admin", LoginTime=DateTime.Now.AddMinutes(-50) }};
27 }
28
29 /// <summary>
30 /// 查找指定主键的用户实例对象。
31 /// </summary>
32 /// <param name="id">用户的主键。</param>
33 /// <returns>返回查找到的用户实例对象。</returns>
34 public User FindUser(int id)
35 {
36 return dataList.FirstOrDefault(user => user.ID == id);
37 }
38
39 /// <summary>
40 /// 获取所有用户的实例集合。
41 /// </summary>
42 /// <returns>返回所有的用户实例。</returns>
43 public IEnumerable<User> UserAll()
44 {
45 return dataList;
46 }
47 }
48 }

      (5)、PatrickLiu.MicroService.ServiceInstance(ASP.NET CORE
WEBAPI),这个就是我们的服务,通过启动多个实例,实现集群,代码很简单,因为重点不是它。


                          这个项目必须引入其他三个项目:

                           PatrickLiu.MicroService.Interfaces

                           PatrickLiu.MicroService.Models

                           PatrickLiu.MicroService.Services

          庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                         【1】、安装Consul服务组件,以支持注册到Consul服务中心。

                    命令:Install-Package Consul

               庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                      可以在项目菜单【依赖项】菜单上点击右键,选择【管理 NuGet 程序包】来安装Consul服务。



                
          【2】、HealthController.cs,主要用于Consul服务的健康检查。                      



                    庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                 
样例代码:

 1 using System;
2 using Microsoft.AspNetCore.Mvc;
3 using Microsoft.Extensions.Configuration;
4
5 namespace PatrickLiu.MicroService.ServiceInstance.Controllers
6 {
7 /// <summary>
8 /// 健康检查的控制器。
9 /// </summary>
10 [ApiController]
11 [Route("api/[controller]")]
12 public class HealthController : ControllerBase
13 {
14 private IConfiguration _configuration;
15
16 /// <summary>
17 /// 初始化该类型的新实例。
18 /// </summary>
19 /// <param name="configuration">配置接口。</param>
20 public HealthController(IConfiguration configuration)
21 {
22 _configuration = configuration;
23 }
24
25 /// <summary>
26 /// 要调用的接口。
27 /// </summary>
28 [HttpGet]
29 [Route("Index")]
30 public IActionResult Index()
31 {
32 Console.WriteLine($"This is HealhController {_configuration["port"]} Invoke");
33 return Ok();
34 }
35 }
36 }

                    

                         
3】、UsersController.cs,主要是业务类型,内容很简单。                     



                    庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                 
样例代码:

  1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Threading;
5 using Microsoft.AspNetCore.Mvc;
6 using Microsoft.Extensions.Configuration;
7 using Microsoft.Extensions.Logging;
8 using PatrickLiu.MicroService.Interfaces;
9 using PatrickLiu.MicroService.Models;
10
11 namespace PatrickLiu.MicroService.ServiceInstance.Controllers
12 {
13 /// <summary>
14 /// 用户的 API 类型。
15 /// </summary>
16 [Route("api/[controller]")]
17 [ApiController]
18 public class UsersController : ControllerBase
19 {
20 #region 私有字段
21
22 private readonly ILogger<UsersController> _logger;
23 private readonly IUserService _userService;
24 private IConfiguration _configuration;
25
26 #endregion
27
28 #region 构造函数
29
30 /// <summary>
31 /// 初始化该类型的新实例。
32 /// </summary>
33 /// <param name="logger">日志记录器。</param>
34 /// <param name="userService">用户服务接口。</param>
35 /// <param name="configuration">配置服务。</param>
36 public UsersController(ILogger<UsersController> logger, IUserService userService, IConfiguration configuration)
37 {
38 _logger = logger;
39 _userService = userService;
40 _configuration = configuration;
41 }
42
43 #endregion
44
45 #region 实例方法
46
47 /// <summary>
48 /// 获取一条记录。
49 /// </summary>
50 /// <param name="id"></param>
51 /// <returns></returns>
52 [HttpGet]
53 [Route("Get")]
54 public User Get(int id)
55 {
56 return _userService.FindUser(id);
57 }
58
59 /// <summary>
60 /// 获取所有记录。
61 /// </summary>
62 /// <returns></returns>
63 [HttpGet]
64 [Route("All")]
65 public IEnumerable<User> Get()
66 {
67 Console.WriteLine($"This is UsersController {this._configuration["port"]} Invoke");
68
69 return this._userService.UserAll().Select((user => new User
70 {
71 ID = user.ID,
72 Name = user.Name,
73 Account = user.Account,
74 Password = user.Password,
75 Email = user.Email,
76 Role = $"{this._configuration["ip"]}:{this._configuration["port"]}",
77 LoginTime = user.LoginTime
78 })); ;
79 }
80
81 /// <summary>
82 /// 超时处理,用于测试服务治理的超时管理。
83 /// </summary>
84 /// <returns></returns>
85 [HttpGet]
86 [Route("Timeout")]
87 public IEnumerable<User> Timeout()
88 {
89 Console.WriteLine($"This is Timeout Start");
90 //超时设置。
91 Thread.Sleep(3000);
92
93 Console.WriteLine($"This is Timeout End");
94
95 return this._userService.UserAll().Select((user => new User
96 {
97 ID = user.ID,
98 Name = user.Name,
99 Account = user.Account,
100 Password = user.Password,
101 Email = user.Email,
102 Role = $"{this._configuration["ip"]}:{this._configuration["port"]}",
103 LoginTime = user.LoginTime
104 })); ;
105 }
106
107 #endregion
108 }
109 }

                      

                         
4】、增加扩展类型:ConsulExtension.cs

                      

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现
                    源码如下:

  1 using Consul;
2 using Microsoft.Extensions.Configuration;
3 using Microsoft.Extensions.Hosting;
4 using System;
5
6 namespace PatrickLiu.MicroService.ServiceInstance.Extensions
7 {
8 /// <summary>
9 /// Consul 静态扩展类。
10 /// </summary>
11 public static class ConsulExtension
12 {
13 /// <summary>
14 ///类型初始化器,初始化 Consul 网址和数据中心。
15 /// </summary>
16 static ConsulExtension()
17 {
18 Uri = new Uri("http://localhost:8500");
19 DataCenter = "dc1";
20 }
21
22 /// <summary>
23 /// 获取或者设置 Consul 的网址。
24 /// </summary>
25 public static Uri Uri { get; set; }
26
27 /// <summary>
28 /// 获取或者设置数据中心。
29 /// </summary>
30 public static string DataCenter { get; set; }
31
32 /// <summary>
33 /// 向 Consul 服务中心注册服务实例。
34 /// </summary>
35 /// <param name="configuration">配置对象。</param>
36 /// <param name="consulServiceName">在 Consul 服务中心注册的服务类别名称,多个实例的 ID 可以属于一个服务类别名称。</param>
37 /// <param name="serviceID">服务实例的主键值,必须唯一。</param>
38 public static void ConsulRegist(this IConfiguration configuration, string consulServiceName, string serviceID)
39 {
40 if (string.IsNullOrEmpty(consulServiceName) || string.IsNullOrWhiteSpace(consulServiceName))
41 {
42 throw new ArgumentNullException("consulServiceName is null");
43 }
44 if (string.IsNullOrEmpty(serviceID) || string.IsNullOrWhiteSpace(serviceID))
45 {
46 throw new ArgumentNullException("serviceID is null.");
47 }
48
49 string consulAddress = configuration["ConsulAddress"];
50 string consulCenter = configuration["ConsulCenter"];
51 if (!string.IsNullOrEmpty(consulAddress) && !string.IsNullOrWhiteSpace(consulAddress))
52 {
53 Uri = new Uri(consulAddress);
54 }
55
56 if (!string.IsNullOrEmpty(consulCenter) && !string.IsNullOrWhiteSpace(consulCenter))
57 {
58 DataCenter = consulCenter;
59 }
60
61 using (ConsulClient client = new ConsulClient(config =>
62 {
63 config.Address = Uri;
64 config.Datacenter = DataCenter;
65 }))
66 {
67 string ip = configuration["ip"];
68 int port = int.Parse(configuration["port"]);
69 int weight = string.IsNullOrWhiteSpace(configuration["weight"]) ? 1 : int.Parse(configuration["weight"]);
70
71
72 client.Agent.ServiceRegister(new AgentServiceRegistration()
73 {
74 ID = serviceID,
75 Name = consulServiceName,
76 Address = ip,
77 Port = port,
78 Tags = new string[] { weight.ToString() },
79 Check = new AgentServiceCheck()
80 {
81 Interval = TimeSpan.FromSeconds(12),
82 HTTP = $"http://{ip}:{port}/API/Health/Index",
83 Timeout = TimeSpan.FromSeconds(5),
84 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(20)
85 }
86 }).Wait();
87 Console.WriteLine($"注册服务:{ip}:{port}--Weight:{weight}");
88 };
89 }
90
91 /// <summary>
92 /// 向 Consul 服务中心注销服务实例。
93 /// </summary>
94 /// <param name="applicationLifetime">配置对象。</param>
95 /// <param name="serviceID">服务实例的主键值,必须唯一。</param>
96 public static void ConsulDown(this IHostApplicationLifetime applicationLifetime, string serviceID)
97 {
98 if (string.IsNullOrEmpty(serviceID) || string.IsNullOrWhiteSpace(serviceID))
99 {
100 throw new ArgumentNullException("serviceID is null");
101 }
102 applicationLifetime.ApplicationStopped.Register(() =>
103 {
104 using (var consulClient = new ConsulClient(config => { config.Address = Uri; config.Datacenter = DataCenter; }))
105 {
106 Console.WriteLine("服务已经退出");
107 consulClient.Agent.ServiceDeregister(serviceID);
108 }
109 });
110 }
111 }
112 }



                        
5】、修改 Startup.cs 类的 Configure 方法的代码。

                      

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                   源码如下:

 1 using Microsoft.AspNetCore.Builder;
2 using Microsoft.AspNetCore.Hosting;
3 using Microsoft.Extensions.Configuration;
4 using Microsoft.Extensions.DependencyInjection;
5 using Microsoft.Extensions.Hosting;
6 using PatrickLiu.MicroService.Interfaces;
7 using PatrickLiu.MicroService.ServiceInstance.Extensions;
8 using PatrickLiu.MicroService.Services;
9 using System;
10
11 namespace PatrickLiu.MicroService.ServiceInstance
12 {
13 /// <summary>
14 /// 应用程序启动配置。
15 /// </summary>
16 public class Startup
17 {
18 /// <summary>
19 /// 构造函数注入配置对象。
20 /// </summary>
21 /// <param name="configuration">配置对象</param>
22 public Startup(IConfiguration configuration)
23 {
24 Configuration = configuration;
25 }
26
27 /// <summary>
28 ///获取配置对象实例。
29 /// </summary>
30 public IConfiguration Configuration { get; }
31
32 /// <summary>
33 /// 配置注入容器的实例。
34 /// </summary>
35 /// <param name="services"></param>
36 public void ConfigureServices(IServiceCollection services)
37 {
38 services.AddControllers();
39 services.AddSingleton<IUserService, UserService>();
40 }
41
42 /// <summary>
43 /// 配置 Http处理的管道。
44 /// </summary>
45 /// <param name="app">应用程序生成器。</param>
46 /// <param name="env">Web宿主环境。</param>
47 /// <param name="applicationLifetime">宿主应用程序的生命周期。</param>
48 public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime applicationLifetime)
49 {
50 #region 中间件配置
51
52 if (env.IsDevelopment())
53 {
54 app.UseDeveloperExceptionPage();
55 }
56
57 //app.UseHttpsRedirection();
58
59 app.UseRouting();
60
61 //增加认证环节
62 app.UseAuthentication();//认证===============================
63
64 app.UseAuthorization();//授权
65
66 app.UseEndpoints(endpoints =>
67 {
68 endpoints.MapControllers();
69 });
70
71 #endregion
72
73 #region Consul 注册
74
75 string serviceID = $"Service:{Configuration["ip"]}:{Configuration["port"]}---{Guid.NewGuid()}";
76 string consuleServiceName = "PatrickLiuService";
77
78 //注册服务。
79 Configuration.ConsulRegist(consuleServiceName, serviceID);
80
81 //注销服务
82 applicationLifetime.ConsulDown(serviceID);
83
84 #endregion
85 }
86 }
87 }



                        
6】、增加4个配置JSON文件。

                     
             appsettings5726.json

             庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                   appsettings5727.json

             庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                   appsettings5728.json

             庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                   appsettings5729.json

             庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

              
          
7】、增加docker-compose.yml批处理了文件。
                     庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                    代码如下:

                    

 1 version: '3.3'
2 services:
3 service1:
4 container_name: serviceInstance_5726
5 environment:
6 - ASPNETCORE_ENVIRONMENT=Production
7 build:
8 context: /root/microService/sourceCode/project/PatrickLiu.MicroService.Docker
9 image: compose-net5.0v1.202125
10 ports:
11 - 5726:80/tcp
12 volumes:
13 - /root/microService/config/appsettings/appsettings5726.json:/app/appsettings.json
14
15 service2:
16 container_name: serviceInstance_5727
17 environment:
18 - ASPNETCORE_ENVIRONMENT=Production
19 image: compose-net5.0v1.202125
20 ports:
21 - 5727:80/tcp
22 command: ["dotnet","/app/publish/PatrickLiu.MicroService.ServiceInstance.dll"]
23 volumes:
24 - /root/microService/config/appsettings/appsettings5727.json:/app/appsettings.json
25
26 service3:
27 container_name: serviceInstance_5728
28 environment:
29 - ASPNETCORE_ENVIRONMENT=Production
30 image: compose-net5.0v1.202125
31 ports:
32 - 5728:80/tcp
33 command: ["dotnet","/app/publish/PatrickLiu.MicroService.ServiceInstance.dll"]
34 volumes:
35 - /root/microService/config/appsettings/appsettings5728.json:/app/appsettings.json
36
37 service4:
38 container_name: serviceInstance_5729
39 environment:
40 - ASPNETCORE_ENVIRONMENT=Production
41 image: compose-net5.0v1.202125
42 ports:
43 - 5729:80/tcp
44 command: ["dotnet","/app/publish/PatrickLiu.MicroService.ServiceInstance.dll"]
45 volumes:
46 - /root/microService/config/appsettings/appsettings5729.json:/app/appsettings.json

      (6)、PatrickLiu.MicroService.Gateway(ASP.NET CORE WEBAPI),网关服务。

          庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                          【1】、安装Ocelot组件,可以实现针对服务管理工作,如:缓存等。

                                    在【程序包管理器控制台】执行命令

                                    命令:Install-Package
Ocelot

              庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                    当然也可以在项目下的【依赖项】上点右键,点击【管理NuGet程序包】菜单,在【浏览】项先安装,输入Ocelot,在右侧安装则可以。



                          【2】、安装Ocelot.Provider.Consul组件,以实现Ocelot和Consul的组合。

                                     在【程序包管理器控制台】执行命令。

                                     命令:Install-Package
Ocelot.Provider.Consul

              庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                     当然也可以在项目下的【依赖项】上点右键,点击【管理NuGet程序包】菜单,在【浏览】项先安装,输入Ocelot.Provider.Consul,在右侧安装则可以。



                          【3】、配置Startup.cs文件。

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现
                    源码如下:

 1 using IdentityServer4.AccessTokenValidation;
2 using Microsoft.AspNetCore.Builder;
3 using Microsoft.AspNetCore.Hosting;
4 using Microsoft.Extensions.Configuration;
5 using Microsoft.Extensions.DependencyInjection;
6 using Ocelot.Cache.CacheManager;
7 using Ocelot.DependencyInjection;
8 using Ocelot.Middleware;
9 using Ocelot.Provider.Consul;
10 using Ocelot.Provider.Polly;
11
12 namespace PatrickLiu.MicroService.Gateway
13 {
14 /// <summary>
15 /// 1、Ocelot 提供网关功能
16 /// 2、Ocelot.Provider.Polly 提供服务治理
17 /// 3、Ocelot.Provider.Consul 提供服务发现
18 /// 4、Ocelot.Cache.CacheManager 提供缓存功能。
19 /// </summary>
20 public class Startup
21 {
22 /// <summary>
23 /// 通过构造函数初始化配置对象。
24 /// </summary>
25 /// <param name="configuration">配置对象。</param>
26 public Startup(IConfiguration configuration)
27 {
28 Configuration = configuration;
29 }
30
31 /// <summary>
32 /// 获取配置对象。
33 /// </summary>
34 public IConfiguration Configuration { get; }
35
36 /// <summary>
37 /// 配置服务。
38 /// </summary>
39 /// <param name="services">服务容器。</param>
40 public void ConfigureServices(IServiceCollection services)
41 {
42 #region 1、在网关中增加鉴权模块
43
44 var authenticationProviderKey = "UserGatewayKey";
45 services.AddAuthentication("Bearer")
46 .AddIdentityServerAuthentication(authenticationProviderKey, options =>
47 {
48 options.Authority = "http://192.168.127.141:7200";
49 options.ApiName = "UserApi";
50 options.RequireHttpsMetadata = false;
51 options.SupportedTokens = SupportedTokens.Both;
52 });
53
54 #endregion
55
56 #region 2、配置网关、网关缓存和服务治理
57
58 services.AddOcelot()//使用 Ocelot 网关服务。
59 .AddConsul()//使用Consul 服务发现控制器。
60 .AddCacheManager(builer => builer.WithDictionaryHandle()) //使用 Ocelot 缓存服务
61 .AddPolly();//支持瞬态故障库----超时、熔断、限流、降级、雪崩效应等都可以做
62
63 #endregion
64 }
65
66 /// <summary>
67 /// 配置中间件。
68 /// </summary>
69 /// <param name="app">应用程序生成器。</param>
70 /// <param name="env">Web宿主环境。</param>
71 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
72 {
73 app.UseOcelot();//配置使用 Ocelot 网关中间件。
74 }
75 }
76 }

          【4】、增加JSON配置文件,文件名:configuration.json。

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现
                    源码如下:
                    

 1 //4、************************************* Ocelot 网关 + Consul 服务发现 *************************************
2 "Routes": [
3 {
4 "DownstreamPathTemplate": "/api/{url}",
5 "DownstreamScheme": "http",
6 "UpstreamPathTemplate": "/gate/{url}",
7 "UpstreamHttpMethod": [ "Get", "Post" ],
8 "UseServiceDiscovery": true,
9 "ServiceName": "PatrickLiuService",
10 "LoadBalancerOptions": { "Type": "RoundRobin" }
11 }
12 ],
13 "GlobalConfiguration": {
14 "BaseUrl": "http://192.168.127.141:6299",
15 "ServiceDiscoveryProvider": {
16 "Host": "192.168.127.141",
17 "Port": 8089,
18 "Type": "Consul",
19 "PollingInterval": 1000,//轮训 Consul,频率毫秒
20 "Token": "footoken"//需要ACL的话
21 }
22 }

          【5】、修改
Program.cs 文件,使用上面增加的JSON配置文件。

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                (7)、PatrickLiu.MicroService.AuthenticationCenter(ASP.NET CORE
WEBAPI),鉴权、授权中心,也可以称“认证服务器”。


                             庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                           【1】、要想认证,必须安装IdentityServer4。

                                      命令:Install-Package IdentityServer4

              庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                      当然也可以在项目下的【依赖项】上点右键,点击【管理NuGet程序包】菜单,在【浏览】项先安装,输入IdentityServer4,在右侧安装则可以。



                           【2】、修改 Startup.cs文件。

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                           【3】、增加一个类型 ClientInitConfig.cs文件。

            庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                     代码样例:

                                      

 1 using IdentityServer4.Models;
2 using System.Collections.Generic;
3
4 namespace PatrickLiu.MicroService.AuthenticationCenter
5 {
6 /// <summary>
7 ///
8 /// </summary>
9 public class ClientInitConfig
10 {
11 /// <summary>
12 ///
13 /// </summary>
14 /// <returns></returns>
15 public static IEnumerable<ApiScope> GetApiScopes()
16 {
17 return new List<ApiScope>
18 {
19 //User API
20 new ApiScope(name: "User.Get", displayName: "获取用户数据"),
21
22 // Health API
23 new ApiScope(name: "Health.Check", displayName: "健康检查."),
24 };
25 }
26
27 /// <summary>
28 /// 能访问的资源权限。
29 /// </summary>
30 /// <returns></returns>
31 public static IEnumerable<ApiResource> GetApiResources()
32 {
33 return new List<ApiResource>
34 {
35 new ApiResource("UserApi","Invoice API")
36 {
37 Scopes={ "User.Get", "Health.Check" }
38 }
39 };
40 }
41
42
43 /// <summary>
44 /// 客户端的认证条件。
45 /// </summary>
46 /// <returns></returns>
47 public static IEnumerable<Client> GetClients()
48 {
49 return new List<Client> {
50 new Client{
51 ClientId="PatrickLiu.MicroService.AuthenticationDemo",
52 ClientSecrets={new Secret("PatrickLiu123456".Sha256()) },
53 AllowedGrantTypes=GrantTypes.ClientCredentials,
54 AllowedScopes=new[]{ "User.Get", "Health.Check" },
55 Claims=new List<ClientClaim>(){
56 new ClientClaim(IdentityModel.JwtClaimTypes.Role,"Admin"),
57 new ClientClaim(IdentityModel.JwtClaimTypes.NickName,"PatrickLiu"),
58 new ClientClaim("eMail","PatrickLiu@sina.com")
59 }
60 }
61 };
62 }
63 }
64 }

    2、编译【PatrickLiu.MicroService.ServiceInstance】项目,发布4个服务实例,独立进程承载,形成服务集群。

                 
再次提醒大家,在开始启动这4个服务实例之前,必须启动Consul服务中心。

                (1)、将【PatrickLiu.MicroService.ServiceInstance】项目编译无误后,然后将项目源码上传至Linux服务器。                  

                           服务器路径为:/root/microService/sourceCode/project

         庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                (2)、为【PatrickLiu.MicroService.ServiceInstance】项目增加4个appsettings.json配置文件,并将配置文件上传至Linux服务器。

                           服务器路径为:/root/microService/config/appsettings

         庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                (3)、为【PatrickLiu.MicroService.ServiceInstance】项目增加Nginx配置文件,并上传至Linux服务器。

                           服务器路径为:/root/microService/config/nginx

          庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

              庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

      (4)、为【PatrickLiu.MicroService.ServiceInstance】项目增加docker-compose.yml配置文件,并上传至Linux服务器。该文件一般建议存放在项目的根目录,如果存在解决方案,则存放在解决方案的根目录。

                             服务器路径为:/root/microService/sourceCode/project/PatrickLiu.MicroService.Docker

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现
              Docker-Compose.yml文件的内容:

 1 version: '3.3'
2 services:
3 service1:
4 container_name: serviceInstance_5726
5 environment:
6 - ASPNETCORE_ENVIRONMENT=Production
7 build:
8 context: /root/microService/sourceCode/project/PatrickLiu.MicroService.Docker
9 image: compose-net5.0v1.202125
10 ports:
11 - 5726:80/tcp
12 volumes:
13 - /root/microService/config/appsettings/appsettings5726.json:/app/appsettings.json
14
15 service2:
16 container_name: serviceInstance_5727
17 environment:
18 - ASPNETCORE_ENVIRONMENT=Production
19 image: compose-net5.0v1.202125
20 ports:
21 - 5727:80/tcp
22 command: ["dotnet","/app/publish/PatrickLiu.MicroService.ServiceInstance.dll"]
23 volumes:
24 - /root/microService/config/appsettings/appsettings5727.json:/app/appsettings.json
25
26 service3:
27 container_name: serviceInstance_5728
28 environment:
29 - ASPNETCORE_ENVIRONMENT=Production
30 image: compose-net5.0v1.202125
31 ports:
32 - 5728:80/tcp
33 command: ["dotnet","/app/publish/PatrickLiu.MicroService.ServiceInstance.dll"]
34 volumes:
35 - /root/microService/config/appsettings/appsettings5728.json:/app/appsettings.json
36
37 service4:
38 container_name: serviceInstance_5729
39 environment:
40 - ASPNETCORE_ENVIRONMENT=Production
41 image: compose-net5.0v1.202125
42 ports:
43 - 5729:80/tcp
44 command: ["dotnet","/app/publish/PatrickLiu.MicroService.ServiceInstance.dll"]
45 volumes:
46 - /root/microService/config/appsettings/appsettings5729.json:/app/appsettings.json

      (5)、为【PatrickLiu.MicroService.ServiceInstance】项目增加Dockerfile配置文件,并将该配置文件上传至服务器,建议该文件存放在项目根目录,如果是解决方案,那就存放在解决方案的根目录。

                            服务器路径为:/root/microService/sourceCode/project/PatrickLiu.MicroService.Docker

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现
              Dockerfile文件的内容:              

 1 #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
2
3 FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
4 WORKDIR /app
5 EXPOSE 80
6 EXPOSE 443
7
8 FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
9 WORKDIR /src
10 COPY ["PatrickLiu.MicroService.ServiceInstance/PatrickLiu.MicroService.ServiceInstance.csproj", "PatrickLiu.MicroService.ServiceInstance/"]
11 COPY ["PatrickLiu.MicroService.Interfaces/PatrickLiu.MicroService.Interfaces.csproj", "PatrickLiu.MicroService.Interfaces/"]
12 COPY ["PatrickLiu.MicroService.Models/PatrickLiu.MicroService.Models.csproj", "PatrickLiu.MicroService.Models/"]
13 COPY ["PatrickLiu.MicroService.Services/PatrickLiu.MicroService.Services.csproj", "PatrickLiu.MicroService.Services/"]
14 RUN dotnet restore "PatrickLiu.MicroService.ServiceInstance/PatrickLiu.MicroService.ServiceInstance.csproj"
15 COPY . .
16 WORKDIR "/src/PatrickLiu.MicroService.ServiceInstance"
17 RUN dotnet build "PatrickLiu.MicroService.ServiceInstance.csproj" -c Release -o /app/build
18
19 FROM build AS publish
20 RUN dotnet publish "PatrickLiu.MicroService.ServiceInstance.csproj" -c Release -o /app/publish
21
22 FROM base AS final
23 WORKDIR /app
24 COPY --from=publish /app/publish .
25 ENTRYPOINT ["dotnet", "PatrickLiu.MicroService.ServiceInstance.dll"]

      (6)、通过docker-compose
up 命令,启动4个服务实例和一个NGINX服务。执行
docker-compose up 命令,必须在docker-compose.yml文件所在的目录,docker-compose.yml和dockerfile两个文件最好都放在一个目录里,建议都存放在项目或者解决方案的根目录里。

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                            命令:#
docker-compose up –d,执行命令,后台运行,必须确保本地有Net5.0镜像,Net5.0的官方镜像拉取太慢,如果想提升镜像拉取速度,请查看我的文章《我教你如何解决 Docker 下载
mcr.microsoft.com 镜像慢的办法
》。

庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现
              庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现
              庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                (7)、检查服务是否启动成功,是否正确注册Consul服务。

                           访问地址:http://192.168.127.141:8500

                                       http://192.168.127.141:9500

                                       http://192.168.127.141:10500

                                       http://192.168.127.141:11500

                             任何一个地址都可以访问。

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                

                (8)、所有服务都启动成功,包括Consul集群和4个服务实例一个Nginx服务。

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                (9)、配置Consul集群的Nginx代理服务,修改Nginx.conf配置文件。

                            服务器路径:/root/microService/config/consulNginx

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                            修改配置文件:nginx.conf,进入当前目录,执行命令:vim
nginx.conf

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                (10)、启动Consul集群的代理服务Nginx服务。

                            命令:#docker
run -d -p 8089:80 -v /root/microService/config/consulNginxLog/:/var/log/nginx/
-v /root/microService/config/consulNginx/nginx.conf:/etc/nginx/nginx.conf
--name consulnginx nginx

                            参数1:/root/microService/config/consulNginxLog/:/var/log/nginx/
通过挂载将容器里面路径:/var/log/nginx/的nginx日志映射到容器外的这个目录:/root/microService/config/consulNginxLog/ 。

                            参数2:/root/microService/config/consulNginx/nginx.conf:/etc/nginx/nginx.conf
通过挂载文件用/root/microService/config/consulNginx/nginx.conf配置文件来替换/etc/nginx/nginx.conf配置文件。

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                (11)、验证Consul集群的 Nginx 地址是否有效。

                           访问地址:http://192.168.127.141:8089/

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



        3、编译【PatrickLiu.MicroService.Gateway】项目,发布3个网关服务实例,独立进程承载,形成服务集群。

         

                (1)、为【PatrickLiu.MicroService.Gateway】项目增加Dockerfile文件,该文件上传到Linux服务器。该文件可以放到项目根目录,如果有解决方案就放在解决方案的根目录。

                         服务器路径:/root/microService/sourceCode/gateway

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                         Dockerfile文件的内容:

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                          如果使用官方的镜像,会报一下错误,内容很多,只是部分截图:

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                         Dockerfile文件增加的内容,二者选其一:

                          FROM
mcr.microsoft.com/dotnet/sdk:5.0-alpine(慢点)


                            FROM
mcr.microsoft.com/dotnet/sdk:5.0-focal




                (2)、为【PatrickLiu.MicroService.Gateway】项目增加docker-compose.yml文件,该文件上传到Linux服务器。该文件可以放到项目根目录,如果有解决方案就放在解决方案的根目录。

                         服务器路径:/root/microService/sourceCode/gateway

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                           Docker-Compose.yml文件内容:

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

              源码如下:

 1 version: '3.3'
2 services:
3 service1:
4 container_name: serviceOcelot_6297_GateWay
5 environment:
6 - ASPNETCORE_ENVIRONMENT=Production
7 build:
8 context: /root/microService/sourceCode/gateway
9 dockerfile: PatrickLiu.MicroService.Gateway/Dockerfile
10 image: compose-net5.0v1.202125-gateway
11 ports:
12 - 6297:80/tcp
13
14 service2:
15 container_name: serviceOcelot_6298_GateWay
16 environment:
17 - ASPNETCORE_ENVIRONMENT=Production
18 image: compose-net5.0v1.202125-gateway
19 ports:
20 - 6298:80/tcp
21 command: ["dotnet","/app/publish/PatrickLiu.MicroService.Gateway.dll"]
22
23 service3:
24 container_name: serviceOcelot_6299_GateWay
25 environment:
26 - ASPNETCORE_ENVIRONMENT=Production
27 image: compose-net5.0v1.202125-gateway
28 ports:
29 - 6299:80/tcp
30 command: ["dotnet","/app/publish/PatrickLiu.MicroService.Gateway.dll"]
31
32 nginx:
33 container_name: serviceOcelotNginx_8083_GateWay
34 image: nginx:latest
35 ports:
36 - 8083:80/tcp
37 restart: always
38 volumes:
39 - /root/microService/config/gatewayNginx/nginx.conf:/etc/nginx/nginx.conf

      (3)、为【PatrickLiu.MicroService.Gateway】项目增加configuration.json配置文件,该文件上传到Linux服务器。

          庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                (4)、使用docker-compose
up -d 命令进行批处理,启动3个网关实例和一个NGINX服务。在执行该命令之前,必须切换到docker-compose.yml文件所在的目录,并且dockerfile文件也要在当前目录下。

          庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                             命令:#docker-compose
up –d

          庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                             中间还有很多内容,省略了。。。

          庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                  

                (5)、我们网关启动完成后,可以通过docker-compose ps命令查看服务是否启动正常,执行该命令必须在docker-compose.yml文件所在的目录,切记。

                             命令:#docker-compose
ps

          庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                (6)、开始验证,在客户端访问我们的客户端是否可以获得数据(这里本地数据)。
                     


                           第一网关地址:http://192.168.127.141:6297/gate/users/all,能获取到数据表示一切成功。

                              截图如下:

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                   刷新地址

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                           第二网关地址:http://192.168.127.141:6298/gate/users/all,能获取到数据表示一切成功。

                              截图如下:

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                   刷新地址

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                           第三网关地址:http://192.168.127.141:6299/gate/users/all,能获取到数据表示一切成功。

                              截图如下:

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                   刷新地址

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                (7)、Ocelot网关集群的Nginx服务已经在Docker-compose.yml配置启动。

                            目录地址:/root/microService/config/gatewayNginx/nginx.conf

                            配置信息:

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                   以下是docker-compose.yml有关nginx配置。

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                 (8)、验证Ocelot网关集群的Nginx服务地址。

                           Nginx地址:http://192.168.127.141:8083/gate/users/all,能获取到数据表示一切成功。

                               截图如下:

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                                   刷新地址后

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                      完美完成负载均衡,心里有些小激动。说明:客户端程序要访问的地址就是这个地址:http://192.168.127.141:8083/gate/users/all



        4、编译【PatrickLiu.MicroService.AuthenticationCenter】项目,发布鉴权、授权中心实例,独立进程承载,形成服务集群。

                 (1)、将【PatrickLiu.MicroService.AuthenticationCenter】项目源码上传到Linux服务器,并将Dockerfile文件存放在更目录。

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                            Dockerfile 文件内容:

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                 (2)、将【PatrickLiu.MicroService.AuthenticationCenter】项目生成镜像文件,切换到Dockerfile文件所在目录,执行生成镜像的命令。

                            命令:#docker
build --no-cache -t authentor3.0v202127 -f Dockerfile .

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                             中间省略很多步骤。。。

                             庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



        
        (3)、查看我们生成鉴权中心的镜像。

                            命令:#docker
images

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                 (4)、查看我们生成鉴权中心的镜像。

                            命令:#docker
run -itd -p 7200:80 authentor3.0v202127

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                 (5)、查看我们生成鉴权中心的容器实例。

                            命令:#dockder
ps –a

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                 (6)、通过PostMan来测试我们鉴权中心是否正常运行。

                            post 请求                 http://192.168.127.141:7200/connect/token

              庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

      (7)、我们的网关设置了权限,现在要访问就要增加token,否则无权访问,返回403。

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



                 (8)、基于Jwt.io网站验证Token数据。

                           访问地址:https://jwt.io/

        庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

三、在Linux系统中基于Docker容器搭建的微服务,我们通过客户端来看一下效果。

             

        1、所有环境都在虚拟机上,客户端程序在本地,看看我辛苦的成果吧。

         

                 客户端我们自己实现的轮训策略,每次刷新,端口号都变,效果如图:

                    5726端口的数据:

      庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                    5727端口的数据:

      庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                    5728端口的数据:

      庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

                    5729端口的数据:

      庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现



      2、我们的结论。

              我们今天的测试虽然完成了,但是还是有很多要改进的地方,比如很多地方我们都可以使用Docker-Compose代替Dockerfile文件,单节点的Docker环境也是问题,可以把环境迁到K8s上,还有其他很多问题,这不是我们最后一版,我们继续努力,完善它。

四、结束语

        
好了,今天就写到这里了。这篇文章也花费了我两周的时间,解决NetCore3.1到Net5.0上所遇到的问题,坑真实不少。在Docker环境中部署东西,或者说在虚拟环境中部署东西,是有一些不一样的,有好处,当然也有弊端。不做不知道,做了才知道问题的多多。俗话说,兵来将挡水来土掩,只要我们勇往直前,道路一定是光明的,再者说,老天不会饿死努力的小鸟的。努力吧,每天进步一点点。