廬山真面目之十二微服務架構基於Docker搭建Consul集羣、Ocelot網關集羣和IdentityServer版本實現

廬山真面目之十二微服務架構基於Docker搭建Consul集羣、Ocelot網關集羣和IdentityServer版本實現

html

1、簡介
       在第七篇文章《廬山真面目之七微服務架構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鑑權、受權的微服務架構。這個任務比較艱鉅,篇幅必定很長,由於包含的內容有點多。固然這個確定不是最終版本,咱們還會繼續演化下去。
           目標框架如圖:
            node

2、搭建Consul服務的集羣。
   

           

        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 pull consul
                

       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

nginx

 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/    


                         啓動:
                                
                         效果:
                                 

               (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/


                         啓動:
                                 
                         效果:
                                 
                    
               (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 -uidocker

 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/


                         啓動:
                                 
                         效果:
                                 

               (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/


                         啓動:
                                
                         效果:
                                               

       3、驗證3個服務器端和一個客戶端是否安裝成功。

               執行這些命令,都要切換到Consul所在的目錄。切記。
               (1)、執行命令查看容器實例
                           命令:#docker ps –a
                               

               (2)、查看Consul成員列表,三個服務器端實例,一個客戶端實例。
              
命令:#docker exec -t clientnode consul members
                  

               3
個server,1個client,狀態是:alive,說明集羣建立成功。

         
(3)、咱們在看看服務器角色的分配是否合適?一主二從,則表示運行成功。
               
命令:#docker exec -t masternode consul operator raft list-peersjson

                                

                (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
                           能看到以下截圖,也能夠說明成功。我只截一個圖了,其餘都相似。

                            

bootstrap

3、搭建微服務測試項目。

          咱們要想搭建微服務架構,第一步,咱們固然要搭建咱們本身的測試項目了,代碼都很簡單,主要是爲了突出各個開源技術點。這是基礎中的基礎,沒有這一步,其餘的都是空中樓閣,沒有說服力了。廢話少說,咱們開始吧。
    
        1、創建測試項目,並編寫各個項目的所需代碼。

                (1)、PatrickLiu.MicroService.Client(ASP.NET CORE MVC),客戶端項目。
                          該項目模仿客戶端程序,固然能夠是你願意的任何客戶端程序,別擡槓,我這裏只是一個簡單的MVC項目,經過地址訪問微服務。

                

                           樣例代碼:
                vim

 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 類庫),定義服務接口,面向接口編程嘛,代碼很簡單,由於重點不是它。

                        

                           樣例代碼:                           windows

 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 類庫),定義實例類型,主要用於數據傳遞,代碼很簡單,由於重點不是它。

                             
         
                           樣例代碼:

 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 類庫),定義服務實現,咱們有了接口,而後基於接口實現具體的服務,代碼很簡單,由於重點不是它。

                             

               樣例代碼:
                            

 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

                           

                         【1】、安裝Consul服務組件,以支持註冊到Consul服務中心。
                    命令:Install-Package Consul
                                   
                      能夠在項目菜單【依賴項】菜單上點擊右鍵,選擇【管理 NuGet 程序包】來安裝Consul服務。

                           【2】、HealthController.cs,主要用於Consul服務的健康檢查。                      
                    
                                 
樣例代碼:

 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,主要是業務類型,內容很簡單。                     
                    
                                 
樣例代碼:

  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
                      
            
                    源碼以下:

  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 方法的代碼。
                      
            
                   源碼以下:

 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
                                      

                                   appsettings5727.json
                                      
                                   appsettings5728.json
                                       
                                   appsettings5729.json
                                      

                         7】、增長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


                (6)、PatrickLiu.MicroService.Gateway(ASP.NET CORE WEBAPI),網關服務。
                           

                          【1】、安裝Ocelot組件,能夠實現針對服務管理工做,如:緩存等。
                                    在【程序包管理器控制檯】執行命令
                                    命令:Install-Package Ocelot
                                    
                                    固然也能夠在項目下的【依賴項】上點右鍵,點擊【管理NuGet程序包】菜單,在【瀏覽】項先安裝,輸入Ocelot,在右側安裝則能夠。

                          【2】、安裝Ocelot.Provider.Consul組件,以實現Ocelot和Consul的組合。
                                     在【程序包管理器控制檯】執行命令。
                                     命令:Install-Package Ocelot.Provider.Consul
                                     
                                     固然也能夠在項目下的【依賴項】上點右鍵,點擊【管理NuGet程序包】菜單,在【瀏覽】項先安裝,輸入Ocelot.Provider.Consul,在右側安裝則能夠。

                          【3】、配置Startup.cs文件。
                                     
                    源碼以下:

 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     /// 一、Ocelot 提供網關功能
16     /// 二、Ocelot.Provider.Polly 提供服務治理
17     /// 三、Ocelot.Provider.Consul 提供服務發現
18     /// 四、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 一、在網關中增長鑑權模塊
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 二、配置網關、網關緩存和服務治理
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。
                                     
                    源碼以下:
                    

 1 //四、************************************* 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配置文件。
                                   

                (7)、PatrickLiu.MicroService.AuthenticationCenter(ASP.NET CORE WEBAPI),鑑權、受權中心,也能夠稱「認證服務器」。
                             

                           【1】、要想認證,必須安裝IdentityServer4。
                                      命令:Install-Package IdentityServer4
                                      
                                      固然也能夠在項目下的【依賴項】上點右鍵,點擊【管理NuGet程序包】菜單,在【瀏覽】項先安裝,輸入IdentityServer4,在右側安裝則能夠。

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

                           【3】、增長一個類型 ClientInitConfig.cs文件。
                                     
                                     代碼樣例:
                                      

 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
                           

                (2)、爲【PatrickLiu.MicroService.ServiceInstance】項目增長4個appsettings.json配置文件,並將配置文件上傳至Linux服務器。
                           服務器路徑爲:/root/microService/config/appsettings
                            

                (3)、爲【PatrickLiu.MicroService.ServiceInstance】項目增長Nginx配置文件,並上傳至Linux服務器。
                           服務器路徑爲:/root/microService/config/nginx
                             
              
                      
                (4)、爲【PatrickLiu.MicroService.ServiceInstance】項目增長docker-compose.yml配置文件,並上傳至Linux服務器。該文件通常建議存放在項目的根目錄,若是存在解決方案,則存放在解決方案的根目錄。
                             服務器路徑爲:/root/microService/sourceCode/project/PatrickLiu.MicroService.Docker
                              
              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
                             
              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-compose up –d,執行命令,後臺運行,必須確保本地有Net5.0鏡像,Net5.0的官方鏡像拉取太慢,若是想提高鏡像拉取速度,請查看個人文章《我教你如何解決 Docker 下載 mcr.microsoft.com 鏡像慢的辦法》。
                                                
              
              

                (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
                             任何一個地址均可以訪問。
                              

                
                (8)、全部服務都啓動成功,包括Consul集羣和4個服務實例一個Nginx服務。
                              

                (9)、配置Consul集羣的Nginx代理服務,修改Nginx.conf配置文件。
                            服務器路徑:/root/microService/config/consulNginx
                             
                            修改配置文件:nginx.conf,進入當前目錄,執行命令:vim nginx.conf
                             

                (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配置文件。
                            

                (11)、驗證Consul集羣的 Nginx 地址是否有效。
                           訪問地址:http://192.168.127.141:8089/
                            

        三、編譯【PatrickLiu.MicroService.Gateway】項目,發佈3個網關服務實例,獨立進程承載,造成服務集羣。
         
                (1)、爲【PatrickLiu.MicroService.Gateway】項目增長Dockerfile文件,該文件上傳到Linux服務器。該文件能夠放到項目根目錄,若是有解決方案就放在解決方案的根目錄。
                         服務器路徑:/root/microService/sourceCode/gateway
                         
                         Dockerfile文件的內容:
                         
                          若是使用官方的鏡像,會報一下錯誤,內容不少,只是部分截圖:
                          
                         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-Compose.yml文件內容:
                          
              源碼以下:

 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服務器。
                           

                (4)、使用docker-compose up -d 命令進行批處理,啓動3個網關實例和一個NGINX服務。在執行該命令以前,必須切換到docker-compose.yml文件所在的目錄,而且dockerfile文件也要在當前目錄下。
                             

                             命令:#docker-compose up –d
                             
                             中間還有不少內容,省略了。。。
                             
                  
                (5)、咱們網關啓動完成後,能夠經過docker-compose ps命令查看服務是否啓動正常,執行該命令必須在docker-compose.yml文件所在的目錄,切記。
                             命令:#docker-compose ps
                              

                (6)、開始驗證,在客戶端訪問咱們的客戶端是否能夠得到數據(這裏本地數據)。
                     

                           第一網關地址:http://192.168.127.141:6297/gate/users/all,能獲取到數據表示一切成功。
                              截圖以下:
                                     
                                   刷新地址
                                     

                           第二網關地址:http://192.168.127.141:6298/gate/users/all,能獲取到數據表示一切成功。
                              截圖以下:
                                     
                                   刷新地址
                                     

                           第三網關地址:http://192.168.127.141:6299/gate/users/all,能獲取到數據表示一切成功。
                              截圖以下:
                                      
                                   刷新地址
                                      

                (7)、Ocelot網關集羣的Nginx服務已經在Docker-compose.yml配置啓動。
                            目錄地址:/root/microService/config/gatewayNginx/nginx.conf
                            配置信息:
                                      
                                   如下是docker-compose.yml有關nginx配置。
                                     

                 (8)、驗證Ocelot網關集羣的Nginx服務地址。
                           Nginx地址:http://192.168.127.141:8083/gate/users/all,能獲取到數據表示一切成功。
                               截圖以下:
                                      
                                   刷新地址後
                                      
                      完美完成負載均衡,內心有些小激動。說明:客戶端程序要訪問的地址就是這個地址:http://192.168.127.141:8083/gate/users/all

        四、編譯【PatrickLiu.MicroService.AuthenticationCenter】項目,發佈鑑權、受權中心實例,獨立進程承載,造成服務集羣。

                 (1)、將【PatrickLiu.MicroService.AuthenticationCenter】項目源碼上傳到Linux服務器,並將Dockerfile文件存放在更目錄。
                            
                            
Dockerfile 文件內容:
                            
                 (2)、將【PatrickLiu.MicroService.AuthenticationCenter】項目生成鏡像文件,切換到Dockerfile文件所在目錄,執行生成鏡像的命令。
                            命令:#docker build --no-cache -t authentor3.0v202127 -f Dockerfile .
                             
                             中間省略不少步驟。。。
                             

        
        (3)、查看咱們生成鑑權中心的鏡像。
                            命令:#docker images
                            

                 (4)、查看咱們生成鑑權中心的鏡像。
                            命令:#docker run -itd -p 7200:80 authentor3.0v202127
                            

                 (5)、查看咱們生成鑑權中心的容器實例。
                            命令:#dockder ps –a
                             

                 (6)、經過PostMan來測試咱們鑑權中心是否正常運行。
                            post 請求                 http://192.168.127.141:7200/connect/token

              
                  
                 (7)、咱們的網關設置了權限,如今要訪問就要增長token,不然無權訪問,返回403。
                            

                 (8)、基於Jwt.io網站驗證Token數據。
                           訪問地址:https://jwt.io/
                           

3、在Linux系統中基於Docker容器搭建的微服務,咱們經過客戶端來看一下效果。
             
        一、全部環境都在虛擬機上,客戶端程序在本地,看看我辛苦的成果吧。
         
                 客戶端咱們本身實現的輪訓策略,每次刷新,端口號都變,效果如圖:

                    5726端口的數據:
                         

                    5727端口的數據:
                         

                    5728端口的數據:
                         

                    5729端口的數據:
                         

      2、咱們的結論。
              咱們今天的測試雖然完成了,可是仍是有不少要改進的地方,好比不少地方咱們均可以使用Docker-Compose代替Dockerfile文件,單節點的Docker環境也是問題,能夠把環境遷到K8s上,還有其餘不少問題,這不是咱們最後一版,咱們繼續努力,完善它。
         

4、結束語         好了,今天就寫到這裏了。這篇文章也花費了我兩週的時間,解決NetCore3.1到Net5.0上所遇到的問題,坑真實很多。在Docker環境中部署東西,或者說在虛擬環境中部署東西,是有一些不同的,有好處,固然也有弊端。不作不知道,作了才知道問題的多多。俗話說,兵來將擋水來土掩,只要咱們一往無前,道路必定是光明的,再者說,老天不會餓死努力的小鳥的。努力吧,天天進步一點點。

相關文章
相關標籤/搜索