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名稱,升級過程如下圖:
這裡會有一個問題,因為有一個時間段會新舊RC共存,由於Service是基於RC的Label建立的,那過來的請求是不是會得到兩種結果?
如果是的話要防止這樣的情況發生就要像上面說的,將整個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中。
部署到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
另外還需要部署Thrift服務端的RC、Service,如圖:
(請注意服務端的Service的Label)
下面是Replication Controllers
呼叫測試,檢視服務的訪問地址,我們的客戶端服務使用的是Nodeport,檢視Nodeport的方式,或者在Dashboard上檢視
然後通過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 由於各種原因,公司要對現有的營銷產品進行微服務化,如果可以,則對公司所有產品逐步進行微服務化。 而本人將作為主力去探索這條路,很艱難,但幹勁十足。整個過會記錄下來,以便以後查閱。 感謝公司!
個推基於Docker和Kubernetes的微服務實踐
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 以其高效、簡便、高水平的可移植性等優勢佔領了絕大部分市場,江湖