自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

從一個(gè)簡(jiǎn)單 API 的發(fā)布到組件化的架構(gòu)思考

開發(fā) 架構(gòu)
在 SaaS 版本的零代碼平臺(tái)中,高級(jí)用戶希望能上傳自己編寫的 WebAPI ,來實(shí)現(xiàn)一些復(fù)雜場(chǎng)景下的業(yè)務(wù)。就需要添加可以通過上傳程序包進(jìn)行發(fā)布部署的功能。

在 SaaS 版本的零代碼平臺(tái)中,高級(jí)用戶希望能上傳自己編寫的 WebAPI ,來實(shí)現(xiàn)一些復(fù)雜場(chǎng)景下的業(yè)務(wù)。就需要添加可以通過上傳程序包進(jìn)行發(fā)布部署的功能。

假設(shè)云服務(wù)器采用華為云,將一個(gè)自定義程序發(fā)布到華為云可以總結(jié)為三個(gè)步驟:

1、將自定義程序包構(gòu)建成鏡像推送到華為云的鏡像倉(cāng)庫(kù)。

2、通過 API 的方式創(chuàng)建 Deploment (無(wú)狀態(tài)負(fù)載)。

3、通過 API 的方式創(chuàng)建 Service ,并和 Deploment 關(guān)聯(lián)。

下面看下簡(jiǎn)單實(shí)現(xiàn)這三個(gè)步驟需要怎么做。

在服務(wù)器上創(chuàng)建目錄 pub ,目錄中創(chuàng)建 Dockerfile 文件,內(nèi)容如下:

FROM swr.cn-north-4.myhuaweicloud.com/xxx/openjdk:latest
ENV PARAMS=""
ENV TZ=PRC
ADD auto-deploy-demo-0.0.1-SNAPSHOT.jar /auto-deploy-demo-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["sh","-c","java -jar /auto-deploy-demo-0.0.1-SNAPSHOT.jar $PARAMS"]
  • From 后面的是在華為云上構(gòu)建的基礎(chǔ) openjdk 鏡像。
  • auto-deploy-demo-0.0.1-SNAPSHOT.jar 為上傳的 jar 包名稱。

在 pub 目錄中再創(chuàng)建一個(gè) pub.sh 文件,用來構(gòu)建鏡像并將鏡像推送到華為云鏡像倉(cāng)庫(kù),pub.sh 內(nèi)容如下:

docker build -t deploy-test .
docker login -u cn-xxxxxx-4@QYL2XOIAQQLUNJQXU6C7 -p 6ba6cbe87d61045efc9505fcd463cfc1aeceb6 swr.cn-xxxxxx.myhuaweicloud.com
docker tag deploy-test:latest swr.cn-xxxxxx.myhuaweicloud.com/xxxxxx/deploy-test:v1.0
docker push swr.cn-xxxxxx.myhuaweicloud.com/xxxxxx/deploy-test:v1.0
  • 首先構(gòu)建本地鏡像。
  • 登錄華為云的鏡像倉(cāng)庫(kù)。
  • 設(shè)置 tag 并推送鏡像。

上傳 jar 包的代碼這里就不放了,下面是連接服務(wù)器并執(zhí)行 pub.sh 文件的代碼:

@GetMapping("/pushImage")
public String pushImage() throws IOException {
SshClient sshClient = SshClientFactory.createSsh("root","xxxxxx","10.211.55.3",22);
sshClient.exec("sh /root/pub/pub.sh", log -> {
});
return "ok";
}

可以看到,上面 jar 包的名稱和鏡像的名稱都是寫死的,真實(shí)場(chǎng)景中,會(huì)根據(jù)上傳的包名和配置的鏡像名來進(jìn)行替換。

鏡像有了,下一步就是創(chuàng)建 Deploment ,也就是華為云的無(wú)狀態(tài)負(fù)載,使用接口的方式來進(jìn)行創(chuàng)建。

調(diào)用華為云的接口,需要先獲取 token :

private String getToken(){
String url="https://iam.xxxxxx.myhuaweicloud.com/v3/auth/tokens";
Map<String, String> headerMap = new HashMap<>(8);
headerMap.put("Content-Type","application/json");
String tokenBody="{\n" +
" \"auth\": {\n" +
" \"identity\": {\n" +
" \"methods\": [\n" +
" \"password\"\n" +
" ],\n" +
" \"password\": {\n" +
" \"user\": {\n" +
" \"name\": \"tokenuser\",\n" +
" \"password\": \"password\",\n" +
" \"domain\": {\n" +
" \"name\": \"domain\"\n" +
" }\n" +
" }\n" +
" }\n" +
" },\n" +
" \"scope\": {\n" +
" \"project\": {\n" +
" \"name\": \"xxxxxx\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
HttpResponse httpResponse= HttpUtil.doPost(url,tokenBody,headerMap);
//String result = httpResponse.body();

String token=httpResponse.header("X-Subject-Token");
return token;
}

需要注意的是,獲取 token 接口入?yún)⒅械挠脩裘兔艽a,需要在「統(tǒng)一身份認(rèn)證」模塊中創(chuàng)建一個(gè)單獨(dú)的用戶。

創(chuàng)建的 Deploment 的代碼如下:

@GetMapping("/createDeploment")
public String createDeploment(){
String token=getToken();
String url="https://96284164-xxxx-11ec-a34d-0255ac1015f0.cce.cn-north-4.myhuaweicloud.com/apis/apps/v1/namespaces/default/deployments";
Map<String, String> headerMap = new HashMap<>(8);
headerMap.put("Content-Type","application/json");
headerMap.put("X-Auth-Token",token);
headerMap.put("X-Cluster-ID","96284164-xxxx-11ec-a34d-0255ac1015f0");
String deploymentBody="{ \n" +
" \"apiVersion\": \"apps/v1\", \n" +
" \"kind\": \"Deployment\", \n" +
" \"metadata\": { \n" +
" \"labels\": { \n" +
" \"app\": \"deploy-test\" \n" +
" }, \n" +
" \"name\": \"deploy-test\" \n" +
" }, \n" +
" \"spec\": { \n" +
" \"replicas\": 1, \n" +
" \"selector\": { \n" +
" \"matchLabels\": { \n" +
" \"app\": \"deploy-test\" \n" +
" } \n" +
" }, \n" +
" \"template\": { \n" +
" \"metadata\": { \n" +
" \"labels\": { \n" +
" \"app\": \"deploy-test\" \n" +
" } \n" +
" }, \n" +
" \"spec\": { \n" +
" \"containers\": [ \n" +
" { \n" +
" \"image\": \"swr.cn-xxxxxx.myhuaweicloud.com/xxxxxx/deploy-test:v1.0\", \n" +
" \"imagePullPolicy\": \"IfNotPresent\", \n" +
" \"name\": \"deploy-test\" \n" +
" } \n" +
" ], \n" +
" \"imagePullSecrets\": [{ \n" +
" \"name\": \"default-secret\" \n" +
" }] \n" +
" } \n" +
" } \n" +
" } \n" +
" }";
HttpResponse httpResponse= HttpUtil.doPost(url,deploymentBody,headerMap);
String result=httpResponse.body();
return result;
}
  • image:使用上面推送到華為云鏡像倉(cāng)庫(kù)中的鏡像名稱。
  • 接口的入?yún)⑹?json 格式,json 中的內(nèi)容,可以參考已創(chuàng)建的無(wú)狀態(tài)負(fù)載中 Yaml 配置的內(nèi)容,當(dāng)然建議還是深入學(xué)習(xí) k8s 的知識(shí),這些參數(shù)什么意思自然就清楚了。

創(chuàng)建完 Deploment 后,還需要?jiǎng)?chuàng)建 Service 才能進(jìn)行訪問,下面是創(chuàng)建 Service 的代碼:

@GetMapping("/createService")
public String createService() {
String token=getToken();
String url="https://96284164-xxxx-11ec-a34d-0255ac1015f0.cce.xxxxxx-4.myhuaweicloud.com/api/v1/namespaces/default/services";
Map<String, String> headerMap = new HashMap<>(8);
headerMap.put("Content-Type","application/json");
headerMap.put("X-Auth-Token",token);
headerMap.put("X-Cluster-ID","96284164-xxxx-11ec-a34d-0255ac1015f0");
String serviceBody="{ \n" +
" \"kind\":\"Service\", \n" +
" \"apiVersion\":\"v1\", \n" +
" \"metadata\":{ \n" +
" \"name\":\"service-deploy-test\", \n" +
" \"creationTimestamp\":null, \n" +
" \"labels\":{ \n" +
" \"app\":\"deploy-test\" \n" +
" } \n" +
" }, \n" +
" \"spec\":{ \n" +
" \"ports\":[{ \n" +
" \"name\":\"http\", \n" +
" \"port\":8082,\n" +
" \"protocol\":\"TCP\", \n" +
" \"targetPort\":8080 \n" +
" }], \n" +
" \"selector\":{ \n" +
" \"app\":\"deploy-test\" \n" +
" }, \n" +
" \"type\":\"ClusterIP\"\n" +
" }\n" +
" }";
HttpResponse httpResponse= HttpUtil.doPost(url,serviceBody,headerMap);
String result=httpResponse.body();

return result;
}
  • name:service-deploy-test ,服務(wù)的名稱,名稱可以在界面中輸入指定,最終會(huì)拼成訪問的地址。
  • app:設(shè)置為 deploy-test ,這個(gè)名稱和 Deploment 的名稱要對(duì)應(yīng)上,否則就掛接不上。
  • type:設(shè)置為 ClusterIP ,表示集群內(nèi)訪問,集群內(nèi)的容器之間可以訪問,如果想要外網(wǎng)訪問,需要設(shè)置為 NodePort ,如果使用了華為云的網(wǎng)關(guān)服務(wù),則需要設(shè)置為 DNAT。
  • port:8082 是訪問時(shí)的端口。
  • targetPort:8080 是 jar 包程序中監(jiān)聽的端口。

依次進(jìn)行鏡像構(gòu)建、創(chuàng)建 Deploment 和 Service 后,在華為云的 cce 無(wú)狀態(tài)負(fù)載中就可以看到 deploy-test 了:

查看詳情的訪問方式:

到這,依次調(diào)用三個(gè)接口就能進(jìn)行自定義 API 到華為云 cce 的部署。

上面的三個(gè)步驟是一個(gè)簡(jiǎn)單的發(fā)布部署的過程,場(chǎng)景很單一,僅僅是將一個(gè) WebAPI 發(fā)布到華為云、形式也很簡(jiǎn)單,只是寫了幾個(gè)簡(jiǎn)單的接口,那么在發(fā)布部署這個(gè)大的場(chǎng)景下,還會(huì)有下面一些情況:

  • 部署環(huán)境可能是阿里云,也可能是自己的服務(wù)器。
  • 部署的程序可能是 WebAPI,也可能是后臺(tái)服務(wù)程序。
  • 如果用戶想要自己輸入訪問的端口,還需要進(jìn)行端口的檢查。
  • 在團(tuán)隊(duì)內(nèi)部也有很多的部署的需求存在。

通過上面的場(chǎng)景,可以將三個(gè)簡(jiǎn)單接口的發(fā)布流程演進(jìn)為一個(gè)發(fā)布部署平臺(tái),架構(gòu)圖如下:

1、將上面發(fā)布華為云 cce 的核心功能抽象到發(fā)布平臺(tái)中。

2、發(fā)布平臺(tái)和發(fā)布的使用方進(jìn)行解耦,通過消息隊(duì)列進(jìn)行連接,因?yàn)槭褂梅娇赡懿恢挂粋€(gè)地方,比如有 SaaS 平臺(tái)和內(nèi)部的運(yùn)維平臺(tái)。

3、在發(fā)布平臺(tái)中提供服務(wù)器管理、執(zhí)行組件管理、檢查組件管理、部署管理等。

  • 服務(wù)器管理:管理服務(wù)器的連接,給執(zhí)行組件使用。
  • 執(zhí)行組件管理:前面提到的構(gòu)建鏡像、創(chuàng)建 Deploment 、創(chuàng)建 Service 可以封裝成不同的執(zhí)行組件。
  • 檢查組件管理:對(duì)執(zhí)行組件中的一些步驟進(jìn)行檢查,比如端口的重復(fù)校驗(yàn)。
  • 部署管理:一個(gè)部署中可以包含多個(gè)步驟,每個(gè)步驟中包含執(zhí)行組件和檢查組件。

這樣當(dāng)有更多的場(chǎng)景需要滿足的時(shí)候,只需要提供更多的執(zhí)行組件就可以,執(zhí)行組件可以在部署管理中進(jìn)行任意的組合,這也滿足了開放封閉原則。

更進(jìn)一步,可以對(duì)執(zhí)行組件和檢查組件抽象出一套標(biāo)準(zhǔn)的規(guī)范和接口,只要按照要求就能編寫出符合自己業(yè)務(wù)的執(zhí)行組件,并對(duì)接到發(fā)布平臺(tái)中,這樣就更靈活了。如果在企業(yè)內(nèi)部使用,不光是發(fā)布平臺(tái)的開發(fā)人員來進(jìn)行執(zhí)行組件的編寫,業(yè)務(wù)方的程序員也能根據(jù)規(guī)范編寫自己的執(zhí)行組件。

殊途同歸,想要軟件能滿足變化、足夠靈活,趨勢(shì)就是組件化。在零代碼平臺(tái)中,這種思想也無(wú)處不在,表單是由各種不同的組件(文本框、數(shù)字框等)構(gòu)成的、頁(yè)面也是由各種組件(列表、圖表等)構(gòu)成的、業(yè)務(wù)規(guī)則也是由各種組件(分支控制、循環(huán)控制、賦值等)構(gòu)成的、流程也是由各種組件(審批、消息等)構(gòu)成的,一切皆組件。

周六在微信視頻號(hào)看崔健的演唱會(huì),中間和竇文濤的訪談環(huán)節(jié)中,老崔說:“現(xiàn)在都講極少主義,但我認(rèn)為極多也是很重要的,是必須經(jīng)歷的過程,有了這種閱歷才能極少”,我覺得很有道理。

零代碼產(chǎn)品中就是將復(fù)雜的、極多的東西放在了背后,讓用戶能夠真正去感受那個(gè)極少,我們的目標(biāo)就是要讓產(chǎn)品既簡(jiǎn)單又強(qiáng)大。

責(zé)任編輯:姜華 來源: 今日頭條
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)