1. 程式人生 > >Openstack+Kubernetes+Docker微服務實踐之路--RPC

Openstack+Kubernetes+Docker微服務實踐之路--RPC

重點來了,本文全面闡述一下我們的RPC是怎麼實現並如何使用的,跟Kubernetes和Openstack怎麼結合。 
在選型一文中說到我們選定的RPC框架是Apache Thrift,它的用法是在Main方法中重啟服務,在Client端連線服務去呼叫,

而我的想法是要跟Dubblo、HSF的用法一樣,因為很多人都熟習這兩個框架的用法,特別是我們好幾個專案都是基於EDAS開發的,而且世面上用Dubbo的公司也很多。

順便再說一下我們對於RPC的幾點要求:

  • 1,相容Dubbo和HSF的使用方法,支援版本和服務分組,支援專案隔離
  • 2,客戶端重試機制,可以配置次數和間隔時間
  • 3,客戶端執行緒池
  • 4,服務端可以平滑無縫升級而不影響客戶端的使用

相容Dubbo就必然要使用Spring框架,那我們就直接上Spring Boot好了,號稱Spring Boot為微服務開發而生,一步到位,將Thrift跟Spring Boot整合。

版本和服務分組可以通過Kubernetes的Service的Label來實現,我們客戶端在查詢服務的時候通過這兩個標籤再加上介面類的Label來定位Service的Cluster IP,這裡不直接使用Service名稱來呼叫服務的原因是通過Label查詢Servcie更加靈活一些,Service的名稱不受限制,隨時可以啟動一個帶有相同Label的新Service來替換舊的Service.
專案隔離可以用Kubernetes的namespace來實現,一個namespace是一個專案,當然專案之間也可以互相呼叫,預設情況下是整個Kubernetes叢集的服務都是可以被呼叫到的如果在沒有指定namespace的情況下。

客戶端重試機制用代理Thrift連線的方式來實現,在連線或介面方法呼叫異常時發起重新連線,參考:https://liveramp.com/engineering/reconnecting-thrift-client/

客戶端連線池是由於在WEB專案中每次使用者發起請求是在一個獨立的執行緒中,而Thrift的Client Socket連線不是執行緒安全的,因此要為每個使用者準備一個Socket連線,有點像資料庫的連線池,這個可以用apache的commons pool2來實現,這個有很多網友的文章可以參考,本文就不在贅述了。

服務端平滑升級可以使用Kubernetes的Kubectl rolling-update來實現,它的機制是先建立一個RC,然後新建一個新版本Pod,停掉一箇舊版本Pod,逐步來完成整個RC的更新,最後刪除舊的RC,把新的RC名稱改為舊的RC名稱,升級過程如下圖:
57355-20161122170700909-1617538406.png

 
這裡會有一個問題,因為有一個時間段會新舊RC共存,由於Service是基於RC的Label建立的,那過來的請求是不是會得到兩種結果?

57355-20161122170722096-1984352336.jpg
57355-20161122170735831-1826459631.jpg

 如果是的話要防止這樣的情況發生就要像上面說的,將整個Service替換,先啟動一個新的Service跟舊的Service有相同Label,然後刪除舊的Service以及RC,在發生服務請求的時候Thrift Client在找不到舊的服務的時候根據Label重新查詢Service就會切換到新的Service上。

 
下面展示一下大概的實現及使用方法,假設你熟習Kubernetes或者簡單瞭解,熟習Docker。

服務端

配置


    <bean class="io.masir.testcloud.thrift.HelloImpl" id="helloImpl"/>
    <bean class="io.masir.testcloud.thrift.ThriftSpringProviderBean" init-method="init" id="providerBean">
        <property name="serviceInterface" value="io.masir.testcloud.thrift.HelloService"/>
        <property name="serviceVersion" value="1.0.0"/>
        <property name="serviceGroup" value="testServiceGroup"/>
        <property name="target" ref="helloImpl"/>
    </bean>

ThriftSpringProviderBean核心程式碼 這是Thrift和Spring整合的核心程式碼,可以借鑑其它網友的Thrift Spring例項。


public class ThriftSpringProviderBean  extends Thread {
 


    private int port = 10809;
    private String serviceInterface;
    private String serviceVersion;
    private String serviceGroup;
    private Object target;
 
    public void run() {
        try {
            TServerSocket serverTransport = new TServerSocket(getPort());
            Class Processor = Class.forName(getServiceInterface() + "$Processor");

            Class Iface = Class.forName(getServiceInterface() + "$Iface");

            Constructor con = Processor.getConstructor(Iface);

            TProcessor processor = (TProcessor) con.newInstance(getTarget());

            TBinaryProtocol.Factory protFactory = new TBinaryProtocol.Factory(true, true);
            TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverTransport);
            args.protocolFactory(protFactory);

            args.processor(processor);
            TServer server = new TThreadPoolServer(args);
            logger.info("Starting server on port " + getPort() + " ...");
            server.serve();
        } catch (TTransportException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public void init() {
        start();
    }
 
    public String getServiceInterface() {
        if(serviceInterface.endsWith(".Iface")){
            serviceInterface = serviceInterface.replace(".Iface","");
        }
        return serviceInterface;
    }


}

客戶端

考慮到Kubernetes是有負載和服務發現的功能,那我們如何跟Thrift整合在一起使用是我們要解決的問題

配置


    <bean class="io.masir.testcloud.thrift.ThriftClientBeanProxyFactory">
        <property name="k8sAPIServer" value="http://100.0.1.5:8080/"/>
        <property name="interfaceName" value="io.masir.testcloud.thrift.HelloService"/>
        <property name="version" value="0.0.1"/>
        <property name="group" value="thrifttest"/>
    </bean>

k8sAPIServer 是Kubernetes的API地址,用來根據 group、version、interfaceName 三個引數查詢服務的叢集地址

ThriftClientBeanProxyFactory 的實現請參考 http://blog.csdn.net/muyuxuebao/article/details/51556066  ,包括重新機制也有了。

另外推薦一個Kubernetes Api訪問的Java元件,非常好用和靈活


        <dependency>
            <groupId>io.fabric8</groupId>
            <artifactId>kubernetes-client</artifactId>
            <version>1.4.14</version>
        </dependency>

生成Image

服務的Dockerfile

FROM  registry2.io/public/java:7
Copy jn-boot-0.0.1.jar /jn-boot.jar
EXPOSE 10809
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo Asia/Shanghai > /etc/timezone
ENV TZ Asia/Shanghai
ENTRYPOINT   java -jar /jn-boot.jar

消費者Dockerfile

FROM  registry2.io/public/java:7
COPY jn-boot-client-0.0.2.jar /jn-boot-client.jar
EXPOSE 10809
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo Asia/Shanghai > /etc/timezone
ENV TZ Asia/Shanghai
ENTRYPOINT   java -jar /jn-boot-client.jar

需要有兩個地方注意一下,使用Copy,每次都要覆蓋拷貝到Image中,另一個是日期應該放在基礎Image中,Build生成Image後Push到我們Registry中。
57355-20161122173006081-1868466033.png

部署到Kubernetes

程式開發或者說開發思路基本實現了,下面就是部署上線測試,Kubernetes的Pods基於Docker執行,那就會用到Registry,一個Pod會是一個Docker容器,所以Kubernetes的流程是從Registry中拿到Image然後啟動一個Dokcer容器,由於我們配置的Registry是有許可權的,所以要先生成Kubernetes的Secrets,

kubectl create secret docker-registry registry2key --docker-server=registry2.io --docker-username=admin --docker-password=1 [email protected] --namespace=thrift-demo

然後在yaml中配置:

apiVersion: v1
kind: ReplicationController
metadata:
  name: thrift-c
  namespace: thrift-demo
spec:
  replicas:1
  selector:
    app: thrift-c
  template:
    metadata:
      name: thrift-c
      labels:
        app: thrift-c
    spec:
      containers:
      - name: thrift-c
        image: registry2.io/thrift/thrift-c:0.0.2
        imagePullPolicy: Always
        ports:
        - containerPort: 9091
      imagePullSecrets:
        - name: registry2key

注意裡面的 imagePullSecrets registry2key

{
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "thrift-c-app",
        "namespace": "thrift-demo"
    },
    "spec": {
        "selector": {
            "app": "thrift-c"
        },
        "ports": [
            {
                "protocol": "TCP",
                "port": 9091,
                "targetPort": 9091
            }
        ]
    }
}

Kubernetes的配置網上有很多,大家分頭去參考,這裡不過多說明,這是一個Thrift客戶端的Kubenetes RC和Service配置,在Kubernetes Master雲主機上通過Kubectl執行並啟動這個RC

57355-20161122170827050-1346828913.png

 
 
另外還需要部署Thrift服務端的RC、Service,如圖:
57355-20161122170857878-118854829.png

(請注意服務端的Service的Label)

下面是Replication Controllers
57355-20161122170912253-1084442531.png

呼叫測試,檢視服務的訪問地址,我們的客戶端服務使用的是Nodeport,檢視Nodeport的方式,或者在Dashboard上檢視
57355-20161122170935378-1951762528.png

然後通過Kubernetes叢集中的任意一臺機器加上NodePort埠就可以訪問我們的Thrift客戶端服務了。

在本文中我們可以看到使用了大量的Kubernetes特性,服務發現、服務負載(基於Service)、滾動升級等等,其中服務發現是在我們添加了Pods數量後會被Service自動發現,包括後面要說的自動擴容,而負載就是Service會在所有Pods中通過某種機制選擇某個Pod來呼叫,事實上還有很多Kubernetes的特性等待我們去使用和發掘,Kubernetes真是一個得力的容器助手,希望我們能把它用好,也希望Kubernetes越來越完善。

在下文中我們將說一說服務的釋出,總不能都通過IP+NodePort的方式來訪問所有WEB服務吧,一定要有一個完美的合適的解決辦法,那會是什麼呢。。。

相關推薦

Openstack+Kubernetes+Docker服務實踐--RPC

重點來了,本文全面闡述一下我們的RPC是怎麼實現並如何使用的,跟Kubernetes和Openstack怎麼結合。  在選型一文中說到我們選定的RPC框架是Apache Thrift,它的用法是在Main方法中重啟服務,在Client端連線服務去呼叫, 而我的想法是要跟Du

Openstack+Kubernetes+Docker服務實踐--彈性擴容

服務上線就要頂的住壓力、扛的住考驗,不然挨說的還是我們這幫做事的兄弟,還記得上圖這個場景嗎 老辦法是服務叢集部署,但總歸有個上限,之前跟阿里合作的時候他們有個彈性計算可以通過設定CPU的閥值來動態擴充套件和收縮計算能力,那時感覺很有逼格,至少在當時我們常規的做法很難做到,

服務實踐-起始

進行 技術棧 com https logs rabbit 服務 ring .com 由於各種原因,公司要對現有的營銷產品進行微服務化,如果可以,則對公司所有產品逐步進行微服務化。 而本人將作為主力去探索這條路,很艱難,但幹勁十足。整個過會記錄下來,以便以後查閱。 感謝公司!

個推基於DockerKubernetes服務實踐

2016年伊始Docker無比興盛,如今Kubernetes萬人矚目。在這個無比需要創新與速度的時代,由容器、微服務、DevOps構成的雲原生席捲整個IT界。個推針對Web服務場景,基於OpenResty和Node.js搭建了微服務框架,提高了開發效率。在微服務的基礎上,我們結合Doc

Netflix 的服務演進

JFrog Netflix DevOps Jenkins 背景Netflix 是全球領先的視頻網站,影片類型包括好萊塢制作,獨立制作電影,本地電影等等,自主研發了“紙牌屋”等知名的電視劇。全球有8千多萬的訂閱會員,覆蓋190個國家(暫未覆蓋中國…),支持一千多種設備類型。Netflix 是 A

服務架構(二):父專案及服務註冊與發現中心(Eureka)搭建

1、建立spring boot父專案 (1.1)file---new----project: (1.2)選擇spring initializr,選擇自己本地安裝的jdk。點選next (1.3)填寫自己的專案資訊,next: (1.4)選擇core-devtools

docker服務部署:六、Rancher管理部署服務

關系 本地倉庫 tab 滾動 hce 同學 官網 blog 學習 docker微服務部署之:五、利用DockerMaven插件自動構建鏡像 一、 什麽是Rancher Rancher是一個開源的企業級容器管理平臺。通過Rancher,企業再也不必自己使用一系列的開源軟件

docker服務部署:七、Rancher進行服務擴容和縮容

href url http 部署 logs doc .html htm 服務 docker微服務部署之:六、Rancher管理部署微服務 docker微服務部署之:七、Rancher進行微服務擴容和

阿里巴巴的服務開源

開發十年,就只剩下這套架構體系了! >>>   

Go服務實踐增刪改查

> 從此篇文章開始,我們來陸續介紹 `go-zero` 開發一個專案所需要的元件和開發實踐。 首先我們從 `model` 層開始,來說說`go-zero` 的API以及封裝細節。首先 `model` 層連線的API集中在`core/stores`。我們先來看看操作 `mysql` 這類資料庫,API方法我們

服務實踐分散式定時任務

承接上篇:上篇文章講到改造 `go-zero` 生成的 `app module` 中的 `gateway & RPC` 。本篇講講如何接入 **非同步任務** 以及 **log的使用**。 ## Delay Job 日常任務開放中,我們會有很多非同步、批量、定時、延遲任務要處理,go-zero中有 `g

(轉)服務框架落地實踐

整合 改善 系統調用 系列 開源 服務 .com 跨語言 拆分 http://www.primeton.com/read.php?id=2276&his=1 一、微服務架構產生的背景 近十年中,互聯網給我們生活帶來了翻天覆地的變化,消費者的生活方式日益數字

從 Spring Cloud 開始,聊聊服務架構實踐

實施 swa 小時 consul 獲取 交互 大內存 二進制文件 gin 【編者的話】隨著公司業務量的飛速發展,平臺面臨的挑戰已經遠遠大於業務,需求量不斷增加,技術人員數量增加,面臨的復雜度也大大增加。在這個背景下,平臺的技術架構也完成了從傳統的單體應用到微服務化的演進。

聊聊服務架構實踐的4大挑戰,3月31日見真章!

微服務 數人雲 docker 當容器化的興起,為應用開發部署帶來變革,也為應用設計架構和運維部署帶來變化; 當持續交付、DevOps、微服務,成為企業在軟件成果對抗當中勝出的有力武器,微服務架構已經隨處可見; 但隨之而至的是微服務框架、微服務監控、微服務配置、微服務治理等一系列挑戰, 從架構到發

Docker+Kubernetes(k8s)服務容器化實踐

k8sDocker+Kubernetes(k8s)微服務容器化實踐網盤地址:https://pan.baidu.com/s/1uVkMsKgfzsJcShlnuLk3ZQ 密碼:1i7q備用地址(騰訊微雲):https://share.weiyun.com/5ZcsfIX 密碼:udrifz Docker官方

Docker+Kubernetes(k8s)服務容器化實踐視頻課程

Docker 第1章 初識微服務微服務的入門,我們從傳統的單體架構入手,看看在什麽樣的環境和需求下一步步走到微服務的,然後再具體了解一下什麽才是微服務,讓大家對微服務的概念有深入的理解。然後我們一起畫一個微服務的架構圖,再從架構上去分析微服務架構的優勢和不足。 ...第2章 微服務帶來的問題及解決方案分析通過

胡忠想|服務架構的Service Mesh實踐

前言 說到Service Mesh,在如今的微服務領域可謂是無人不知、無人不曉,被很多人定義為下一代的微服務架構。 Service Mesh在誕生不到兩年的時間裡取得令人矚目的發展,在國內外都湧現出一批具有代表性的新產品,最著名的莫過於Google、IBM領導的Istio,也是Service Mesh技術

聊聊服務架構實踐的4大挑戰,3月31日見真章!_Kubernetes中文社群

當容器化的興起,為應用開發部署帶來變革,也為應用設計架構和運維部署帶來變化; 當持續交付、DevOps、微服務,成為企業在軟體成果對抗當中勝出的有力武器,微服務架構已經隨處可見; 但隨之而至的是微服務框架、微服務監控、微服務配置、微服務治理等一系列挑戰, 從架構到釋出,挑戰重重,該如何應

從 Spring Cloud 開始,聊聊服務架構的實踐

使用微服務架構開發應用程式,我們實際上是針對一個個微服務進行設計、開發、測試、部署,因為每個服務之間是沒有彼此依賴的,大概的交付流程就像上圖這樣。設計階段: 架構組將產品功能拆分為若干微服務,為每個微服務設計 API 介面(例如 REST API),需要給出 API 文件,包括 API 的名稱、版本、請求引

【 專欄 】- Docker+Kubernetes(k8s)服務容器化實踐

Docker+Kubernetes(k8s)微服務容器化實踐 Docker官方支援Kubernetes, Kubernetes是容器編排最大贏家,Kubernetes 以其高效、簡便、高水平的可移植性等優勢佔領了絕大部分市場,江湖