spring cloud通過sidecar支持異構(gòu)語言微服務

1 背景

spring cloud是java應用世界中微服務的事實標準管引,它提供了非常豐富且完整的微服務組件,且非常方便與java應用程序進行集成闯两。但是褥伴,由于spring cloud很多功能是通過java jar包以SDK調(diào)用的形式集成到應用程序中的(如eureka client谅将,spring cloud config client等),使用其他語言(如go重慢、python饥臂、php、js等)開發(fā)的應用程序并不能直接使用這些jar包集成到spring cloud微服務系統(tǒng)中似踱。但是隅熙,由于各種現(xiàn)實的原因,要求業(yè)務系統(tǒng)所有的組件都采用java技術棧不是很現(xiàn)實核芽。同時囚戚,采用微服務技術的一個重要出發(fā)點是系統(tǒng)的不同組件可以獨立選擇技術棧,進行獨立設計轧简、開發(fā)弯淘、測試和部署升級,如果約束微服務系統(tǒng)的所有組件都必須采用單一的java技術棧吉懊,也違背了微服務設計思想的初衷庐橙。如果要讓非java應用集成到spring cloud系統(tǒng)中,一種方式是為每種語言開發(fā)一系列相應的客戶端組件借嗽,嵌入到應用程序中态鳖,仍然通過SDK調(diào)用的方式進行集成,與當前java應用程序采取的方式一樣恶导,這種方式是侵入式的浆竭;另一種方式是通過sidecar的方式,引入一個單獨的中間組件惨寿,非java應用程序只要做極少的適配邦泄,就可以復用spring cloud大部分微服務基礎能力,這種方式(基本上可以說)是非侵入式的裂垦。這里通過介紹一個sidecar的實現(xiàn)顺囊,即netflix公司提供的spring cloud netflix sidecar,來看看spring cloud如何通過sidecar集成非java應用程序蕉拢。

2 spring cloud netflix sidecar工作原理

2.1 java應用程序與非java應用程序通過sidecar相互調(diào)用過程

2.1.1 java應用程序調(diào)用非java應用程序服務過程

image.png

1)sidecar向注冊中心注冊自己

2)java-app從注冊中心獲取sidecar的實例列表信息

3)java-app從sidecar的實例列表中基于一定的負載均衡算法選擇一個具體的實例特碳,并將請求發(fā)送給選中的實例

4)sidecar接收到請求后,發(fā)現(xiàn)是調(diào)用自己代理的non-java-app服務晕换,然后將請求轉(zhuǎn)發(fā)給相應的non-java-app

5)non-java-app處理請求午乓,將響應發(fā)送給sidecar

6)sidecar將響應轉(zhuǎn)發(fā)給java-app

2.1.2 非java應用程序調(diào)用java應用程序服務過程

image.png

1)java-app向注冊中心注冊自己

2)non-java-app將請求發(fā)送給sidecar,請求url path的第一段值為java-app的服務名

3)sidecar從注冊中心獲取java-app的實例列表信息

4)sidecar從java-app的實例列表中基于一定的負載均衡算法選擇一個具體的實例闸准,并將請求發(fā)送給選中的實例

5)java-app處理請求益愈,將響應發(fā)送給sidecar

6)sidecar將響應轉(zhuǎn)發(fā)給non-java-app

2.2 spring cloud netflix sidecar內(nèi)部原理

spring cloud netflix sidecar內(nèi)部的核心工作是由netflix開源的微服務網(wǎng)關組件zuul提供的,sidecar其實是在zuul基礎上進行的二次開發(fā)夷家。

1)sidecar與non-java-app必須部署在同一個節(jié)點上蒸其,且一個sidecar唯一對應一個non-java-app

2)sidecar相當于non-java-app的代理敏释,由sidecar向注冊中心注冊服務,其他微服務看到的non-java-app的服務名是由sidecar注冊的枣接,服務端口號是sidecar的端口號

3)注冊中心如何檢測non-java-app的健康狀態(tài)

非java應用程序如果希望通過sidecar集成到spring cloud系統(tǒng)中颂暇,需要提供一個health檢測接口,當非java應用程序狀態(tài)正常時但惶,這個health接口返回一個json字符串耳鸯,內(nèi)容如下所示:

{
    "status":"UP"
}

sidecar在向注冊中心反饋自己的健康狀態(tài)時,會調(diào)用相應非java應用程序提供的health檢測接口膀曾,這樣只有非java應用程序狀態(tài)正常時县爬,sidecar在注冊中心注冊的相應服務實例的狀態(tài)才是正常的。

4)sidecar如何確定請求是來自于被代理的non-java-app還是發(fā)送給non-java-app的

當sidecar接收到請求時添谊,會判斷http url的path路徑的第一段是不是一個服務名财喳。如果是,則會根據(jù)注冊中心注冊的實例信息斩狱,通過一定的負載均衡算法選擇一個具體的實例耳高,將請求轉(zhuǎn)發(fā)給選擇的實例。否則所踊,sidecar則認為是調(diào)用自己代理的非java應用程序服務泌枪,將請求的host改為127.0.0.1,port改為相應非java應用程序的port秕岛,然后將請求轉(zhuǎn)發(fā)給相應的非java應用程序

3 spring cloud netflix sidecar應用舉例

下面通過一個java應用程序與一個go應用程序通過spring cloud微服務相互調(diào)用來舉例說明sidecar是如何支持多語言微服務集成的碌燕,本例中使用的注冊中心為eureka。

3.1 go應用程序?qū)嵗?/h2>

go應用程序的代碼片段如下所示:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

// 提供的健康檢測接口
func health(w http.ResponseWriter, r *http.Request)  {
    m := map[string]string{"status": "UP"}
    mjson, _ := json.Marshal(m)
    w.Header().Set("Content-Type", "application/json")
    w.Write(mjson)
}

func hellogo(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "hellogo")
}

func remoteHellojava(w http.ResponseWriter, r *http.Request) {
    // 通過sidecar調(diào)用其它微服務的接口继薛,8004是sidecar的服務端口修壕,java-app-service是服務名,/hellojava是服務路徑
    resp, _ := http.Get("http://172.18.182.27:8004/java-app-service/hellojava")
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Fprintf(w, string(body))
}

func main() {

    http.HandleFunc("/health.json", health)
    http.HandleFunc("/hellogo", hellogo)
    http.HandleFunc("/remoteHellojava", remoteHellojava)
    // 監(jiān)聽的端口是8093
    err := http.ListenAndServe(":8093", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

該應用監(jiān)聽的port為8093遏考,提供了三個http接口:

1)/health.json

用于sidecar檢測應用的健康狀態(tài)慈鸠,eureka則通過sidecar間接確定應用的健康狀態(tài)

2)/hellogo

應用提供的服務接口,被調(diào)用時返回字符串"hellogo"

3)/remoteHellojava

該接口會通過調(diào)用sidecar的接口來間接調(diào)用其他微服務的接口诈皿。url格式為:

http://{sidecar-host}:{sidecar-port}/{目的服務的服務名}/{目的服務的path}

3.2 sidecar實例

sidecar代碼片段如下:

@EnableSidecar
@EnableEurekaClient
@SpringBootApplication
public class SidecarApplication {

    public static void main(String[] args) {
        SpringApplication.run(SidecarApplication.class, args);
    }

}

可見林束,sidecar的基礎代碼非常簡單,只要添加幾個注解即可稽亏。@EnableSidecar注解用來開啟sidecar功能

基礎配置如下:

# 服務端口號
server.port: 8004

# 服務名
spring:
  application:
    name: go-app-service

# 服務注冊和發(fā)現(xiàn)
eureka:
  client:
    healthcheck:
      enabled: true
    serviceUrl:
      defaultZone: http://127.0.0.1:8002/eureka/
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}

# sidecar配置
sidecar:
  port: 8093
  health-uri: http://localhost:8093/health.json

從上述的配置可見,除了跟sidecar相關的兩個配置項:sidecar.port和sidecar.health-uri缕题,其余的配置跟一個普通的spring cloud應用程序相同截歉,更準確的說,跟配置微服務網(wǎng)關zuul是一樣的烟零。

sidecar.port用來告訴sidecar go應用程序監(jiān)聽的服務端口(不提供go應用程序host的原因是sidecar調(diào)用go應用程序服務時固定使用127.0.0.1地址)瘪松,sidecar.health-uri用來告訴sidecar go應用程序提供的健康檢測接口

分別啟動go應用程序和sidecar记罚,可以在eureka中看到sidecar注冊的服務實例烟馅,如下:

GO-APP-SERVICE  n/a (1) (1) UP (1) - 172.18.182.27:8004

3.3 java應用程序?qū)嵗?/h2>

java應用的代碼片段如下:

@FeignClient(value = "go-app-service")
@RequestMapping(value = "/")
public interface GoAppServiceFeignClient {

    @GetMapping(value = "/hellogo")
    String hello();

}

通過feign調(diào)用遠端微服務,@FeignClient(value = "go-app-service")指定微服務的名字捆憎,從前面可知,這個服務名即sidecar向eureka注冊的服務名

@RestController
@RequestMapping(value = "/")
public class Controller {

    @Autowired
    private GoAppServiceFeignClient feignClient;

    @GetMapping(value = "/hellojava")
    public String hellojava() {
        return "hellojava";
    }

    @GetMapping(value = "/remoteHellogo")
    public String hellogo() {
        return feignClient.hello();
    }

}



@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class EurekaClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaClientApplication.class, args);
    }

}

配置文件內(nèi)容如下:

server:
  port: 8003

spring:
  application:
    name: java-app-service

eureka:
  client:
    healthcheck:
      enabled: true
    serviceUrl:
      defaultZone: http://127.0.0.1:8002/eureka/
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}

啟動程序太伊,可以在eureka中看到應用程序注冊的服務實例曙痘,如下:

JAVA-APP-SERVICE    n/a (1) (1) UP (1) - 172.18.182.27:8003

3.4 相互調(diào)用測試

調(diào)用go應用程序的/remoteHellojava接口,返回hellojava,說明調(diào)用成功

% curl http://localhost:8093/remoteHellojava

hellojava

調(diào)用java應用程序的/remoteHellogo接口超燃,返回hellogo届良,說明調(diào)用成功

% curl http://localhost:8003/remoteHellogo

hellogo
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伙窃,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子样漆,更是在濱河造成了極大的恐慌为障,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件放祟,死亡現(xiàn)場離奇詭異鳍怨,居然都是意外死亡,警方通過查閱死者的電腦和手機跪妥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門鞋喇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人眉撵,你說我怎么就攤上這事侦香。” “怎么了纽疟?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵罐韩,是天一觀的道長。 經(jīng)常有香客問我污朽,道長散吵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任蟆肆,我火速辦了婚禮矾睦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘炎功。我一直安慰自己枚冗,他們只是感情好,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布蛇损。 她就那樣靜靜地躺著官紫,像睡著了一般肛宋。 火紅的嫁衣襯著肌膚如雪州藕。 梳的紋絲不亂的頭發(fā)上束世,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音床玻,去河邊找鬼毁涉。 笑死,一個胖子當著我的面吹牛锈死,可吹牛的內(nèi)容都是我干的贫堰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼待牵,長吁一口氣:“原來是場噩夢啊……” “哼其屏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缨该,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤偎行,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后贰拿,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛤袒,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年膨更,在試婚紗的時候發(fā)現(xiàn)自己被綠了妙真。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡荚守,死狀恐怖珍德,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情矗漾,我是刑警寧澤锈候,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站缩功,受9級特大地震影響晴及,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嫡锌,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一虑稼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧势木,春花似錦蛛倦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽及皂。三九已至,卻和暖如春且改,著一層夾襖步出監(jiān)牢的瞬間验烧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工又跛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碍拆,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓慨蓝,卻偏偏與公主長得像感混,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子礼烈,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容