spring cloud+.net core搭建微服務架構:服務發現(二)

前言

上篇文章實際上只講了服務治理中的服務註冊,服務與服務之間如何調用呢?傳統的方式,服務A調用服務B,那麼服務A訪問的是服務B的負載均衡地址,經過負載均衡來指向到服務B的真實地址,上篇文章已經說了這種方式的缺點。那麼下面講如何在spring cloud+dotnet core的應用下進行服務調用。html

代碼實現

假設一種場景,有一個訂單服務,有一個產品服務,其中產品服務是由兩個服務節點組成一個集羣。需求是訂單服務訪問產品服務的一個API接口。根據上一章文章的內容建立3個應用程序ServiceOne(端口8010),ServiceTwo(端口8011),ServiceThree(8012)。其中ServiceOne設置應用程序名稱爲order。ServiceTwo和ServiceThree的應用程序名稱爲product,作成集羣。java

ServiceOne.appsettings.jsongit

{
    "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
            "Default": "Warning"
        }
    },
    "spring": {
        "application": {
            "name": "order"
        }
    },
    "eureka": {
        "client": {
            "serviceUrl": "http://localhost:5000/eureka/"
        },
        "instance": {
            "port": 8010
        }
    }
}

ServiceOne.Controllers.ValuesController.CSgithub

private readonly DiscoveryHttpClientHandler _handler;
private const string ProductUrl = "http://product/api/values";

public ValuesController(IDiscoveryClient client, ILoggerFactory logFactory)
{
    _handler = new DiscoveryHttpClientHandler(client);
}

[HttpGet("product")]
public async Task<string> GoProductAsync()
{
    var client = new HttpClient(_handler, false);
    return await client.GetStringAsync(ProductUrl);
}

ServiceTwo.appsettings.jsonspring

{
    "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
            "Default": "Warning"
        }
    },
    "spring": {
        "application": {
            "name": "product"
        }
    },
    "eureka": {
        "client": {
            "serviceUrl": "http://localhost:5000/eureka/"
        },
        "instance": {
            "port": 8011
        }
    }
}

ServiceTwo.appsettings.jsondocker

{
    "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
            "Default": "Warning"
        }
    },
    "spring": {
        "application": {
            "name": "product"
        }
    },
    "eureka": {
        "client": {
            "serviceUrl": "http://localhost:5000/eureka/"
        },
        "instance": {
            "port": 8012
        }
    }
}

爲了展示訪問的差別,設置不一樣的返回值。
ServiceTwo.Controllers.ValuesController.csjson

[HttpGet]
public string Get()
{
    return "ServiceTwo";
}

ServiceThree.Controllers.ValuesController.csapi

[HttpGet]
public string Get()
{
    return "ServiceThree";
}

同時啓動這3個項目,先看看服務中心http://localhost:5000/
image
這個3個應用程序都已經註冊到了服務中心。ServiceOne被註冊到ORDER,ServiceTwo和ServiceThree註冊到了PRODUCT。
分別訪問
http://localhost:8011/api/values 返回ServiceTwo
http://localhost:8012/api/values 返回ServiceThree
證實這兩個服務是沒有問題的。
再訪問http://localhost:8010/api/values/product,
如圖所示,分別返回了「ServiceTwo」和「ServiceThree」,多刷新幾回,發現結果是來回變更的,這說明服務中心幫咱們實現了負載均衡。架構

image

image

咱們再作一個測試,斷開ServiceTwo這個應該程序。咱們繼續訪問http://localhost:8010/api/values/product,發現一次錯誤,一次正常返回ServiceThree。30秒之後(可配置)再訪問正常返回ServiceThree,同時發現服務中心已經踢掉了端口爲8011的應用程序(ServiceTwo)。app

image

後記

經過上面3個實例咱們模擬了分佈式的調用場景,其中Order訪問Product集羣的時候,並無指定具體的地址,而是指定了服務名稱(product),服務中心自動分配了地址,並實現了負載均衡。聯繫實際應用場景,配合docker,咱們能夠快速的對某個服務進行添加,再也不須要維護服務節點。同時某個服務節點掛掉之後,服務中心也會踢出這個服務節點(會有短暫的不可用)。結合CAP理論來講,服務中心知足了AP。
這篇文章講解了服務之間的調用,咱們實際的應用場景,還有各類客戶端(IOS,Andriod,Web...)來訪問,而服務通常是內網不對外暴露的,因此客戶端訪問服務的時候就須要有一個專門對外暴露的入口,那麼就引入了下篇文章的API網關。

示例代碼

全部代碼均上傳github。代碼按照章節的順序上傳,例如第一章demo1,第二章demo2以此類推。
求推薦,大家的支持是我寫做最大的動力,個人QQ羣:328438252,交流微服務。

傳送門

參考資料

java部分

.net部分

相關文章
相關標籤/搜索