SpringCloud微服務實例(K8S民傻、Eureka、Zuul、Skywalking))

1漓踢、說明

在K8s Paas平臺搭建SpringCloud微服務框架牵署,進行微服務開發(fā)。網(wǎng)關采用Zuul1喧半、服務注冊與發(fā)現(xiàn)采用Eureka奴迅。鏈路跟蹤與日志采集采用Skywalking。Skywalking日志采集是Skywalking8.5.0版本之后的功能挺据,Skywalking日志采集采用服務工程主動推送的方式取具,與logback集成,可以滿足中小型系統(tǒng)的日志采集和分析扁耐,數(shù)據(jù)庫可選用elasticsearch者填,能保證良好的搜索性能。


新建一個k8s命名空間進行實驗:

Yaml:

apiVersion: v1

kind: Namespace

metadata:

??? name: sclouds

??? labels:

?????? name: sclouds


設置默認命名空間:

kubectl config set-context $(kubectl config current-context) --namespace=sclouds


2做葵、Eureka容器集群

2.1.StatefulSet占哟、Headless Service

Eureka搭建容器集群,需要依賴k8s的statefulset組件酿矢。Eureka-server的每個實例需要相互同步狀態(tài)榨乎。

StatefulSet是為了解決有狀態(tài)服務的問題(對應Deployments和ReplicaSets是為無狀態(tài)服務而設計),其應用場景包括

穩(wěn)定的持久化存儲瘫筐,即Pod重新調度后還是能訪問到相同的持久化數(shù)據(jù)蜜暑,基于PVC來實現(xiàn)。

穩(wěn)定的網(wǎng)絡標志策肝,即Pod重新調度后其PodName和HostName不變肛捍,基于Headless Service(即沒有Cluster IP的Service)來實現(xiàn)。

有序部署之众,有序擴展拙毫,即Pod是有順序的,在部署或者擴展的時候要依據(jù)定義的順序依次依次進行(即從0到N-1棺禾,在下一個Pod運行之前所有之前的Pod必須都是Running和Ready狀態(tài))缀蹄,有序收縮,有序刪除(即從N-1到0)膘婶。

使用StatefulSet缺前,StatefulSet中每個Pod的DNS就是固定的,格式為

??? statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local

serviceName為Headless Service的名字0..N-1為Pod所在的序號悬襟,從0開始到N-1statefulSetName為StatefulSet的名字namespace為服務所在的namespace衅码,Headless Service和StatefulSet必須在相同的namespacecluster.local為Cluster Domain


2.2.Ecureka Springboot鏡像

集群由兩個ecureka服務組成,服務工程基于Springboot開發(fā)脊岳,打包成jar包逝段,最后打包成docker鏡像在k8s上部署筛璧。

Sprinboot版本:2.6.2

SpringCloud版本:2021.0.1

pom.xml設置,引入spring-cloud-starter-netflix-eureka-server:

引入spring-boot-starter-web惹恃、spring-cloud-starter-netflix-eureka-server

? ? <dependencies>

? ? ? ? <dependency>

? ? ? ? ? ? <groupId>org.springframework.boot</groupId>

? ? ? ? ? ? <artifactId>spring-boot-starter-web</artifactId>

? ? ? ? </dependency>

? ? ? ? <dependency>

? ? ? ? ? ? <groupId>org.springframework.cloud</groupId>

? ? ? ? ? ? <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>

? ? ? ? </dependency>

? ? ? ? <dependency>

? ? ? ? ? ? <groupId>org.springframework.boot</groupId>

? ? ? ? ? ? <artifactId>spring-boot-starter-test</artifactId>

? ? ? ? ? ? <scope>test</scope>

? ? ? ? </dependency>

? ? </dependencies>

? ? <dependencyManagement>

? ? ? ? <dependencies>

? ? ? ? ? ? <dependency>

? ? ? ? ? ? ? ? <groupId>org.springframework.cloud</groupId>

? ? ? ? ? ? ? ? <artifactId>spring-cloud-dependencies</artifactId>

? ? ? ? ? ? ? ? <version>${spring-cloud.version}</version>

? ? ? ? ? ? ? ? <type>pom</type>

? ? ? ? ? ? ? ? <scope>import</scope>

? ? ? ? ? ? </dependency>

? ? ? ? </dependencies>

</dependencyManagement>

application.properties屬性設置:

spring.application.name=register-server

server.port=8000

management.server.port=8001

eureka.instance.leaseRenewalIntervalInSeconds=10

eureka.instance.leaseExpirationDurationInSeconds=30

eureka.instance.hostname=${MY_POD_NAME}.register-server

eureka.instance.prefer-ip-address=true

eureka.client.fetch-registry=true

eureka.client.register-with-eureka=true

eureka.client.service-url.defaultZone=http://register-server-0.register-server:8000/eureka/,http://register-server-1.register-server:8000/eureka/

eureka.client.service-url.registryFetchIntervalSeconds=10

eureka.client.service-url.disable-delta=true

eureka.server.evictionIntervalTimerInMs=4000

eureka.server.enable-self-preservation=false

Dockfile:

FROM java:8

VOLUME /tmp

ADD eurekaclu-0.0.1-SNAPSHOT.jar /eurekaclu-0.0.1-SNAPSHOT.jar

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/eurekaclu-0.0.1-SNAPSHOT.jar"]

2.3.k8s service服務暴露

使用2.2的鏡像部署statefulset夭谤。Service關聯(lián)暴露服務。為了方便訪問巫糙,設置成nodePort類型朗儒,暴露外網(wǎng)端口。

statefulset:

apiVersion: apps/v1

kind: StatefulSet

metadata:

? name: register-server

? labels:

? ? service: register-server

spec:

? replicas: 2

? serviceName: register-server

? selector:

? ? matchLabels:

? ? ? service: register-server

? template:

? ? metadata:

? ? ? labels:

? ? ? ? service: register-server

? ? ? annotations:

? ? ? ? service: register-server

? ? spec:

? ? ? containers:

? ? ? ? - name: register-server

? ? ? ? ? image: dw/eurekaclu-2

? ? ? ? ? imagePullPolicy: IfNotPresent

? ? ? ? ? env:

? ? ? ? ? - name: MY_POD_NAME

? ? ? ? ? ? valueFrom:

? ? ? ? ? ? ? fieldRef:

? ? ? ? ? ? ? ? fieldPath: metadata.name

? ? ? ? ? ports:

? ? ? ? ? ? - name: http

? ? ? ? ? ? ? containerPort: 8000

? ? ? ? ? ? ? protocol: TCP

? ? ? ? ? readinessProbe:

? ? ? ? ? ? httpGet:

? ? ? ? ? ? ? path: /actuator/health

? ? ? ? ? ? ? port: 8001

? ? ? ? ? ? ? scheme: HTTP

? ? ? ? ? ? failureThreshold: 3

? ? ? ? ? ? initialDelaySeconds: 60

? ? ? ? ? ? periodSeconds: 10

? ? ? ? ? ? successThreshold: 1

? ? ? ? ? ? timeoutSeconds: 10

? ? ? ? ? resources:

? ? ? ? ? ? limits:

? ? ? ? ? ? ? # cpu: 100m

? ? ? ? ? ? ? memory: 1Gi

? ? ? ? ? ? requests:

? ? ? ? ? ? ? ? # cpu: 100m

? ? ? ? ? ? ? memory: 1Gi

? ? ? ? ? volumeMounts:

? ? ? ? ? - mountPath: /Charts

? ? ? ? ? ? name: data

? ? ? volumes:

? ? ? - name: data

? podManagementPolicy: "Parallel"

Service:

apiVersion: v1

kind: Service

metadata:

? name: register-server

? labels:

? ? service: register-server

spec:

? type: NodePort

? ports:

? ? - port: 8000

? ? ? targetPort: 8000

? ? ? protocol: TCP

? ? ? name: http

? ? ? nodePort: 30111

? selector:

? ? service: register-server

依次應用statefulset参淹、service醉锄,部署兩個statefulset:


ecureka satefulset

這樣可以得到兩個ecurka-server的集群內(nèi)url,和2.2節(jié)的屬性設置對應:

register-server-0.register-server:8000

register-server-1.register-server:8000

導出nodePort浙值,瀏覽器登錄驗證:


注冊中心


3.Zuul1容器集群

Zuul1是springcloud早期的服務網(wǎng)關恳不,這里使用舊一點的穩(wěn)定版本。

3.1.zuul1 springboot

Zuul也要注冊到eureka开呐,需要引入eureka-client和netflix-zuul烟勋。服務注冊ecureka使用上一章搭建的集群,根據(jù)k8s服務url規(guī)則筐付,ecureka服務的url為http://register-server.sclouds.svc.cluster.local:8000/eureka/卵惦,k8s服務進行負載分發(fā)到兩個stateful實例

Springboot版本:2.1.8

SpringCloud版本:Greenwich.SR2

Pom.xml:

<dependency>

? ? <groupId>org.springframework.cloud</groupId>

? ? <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

<dependency>

? ? <groupId>org.springframework.cloud</groupId>

? ? <artifactId>spring-cloud-starter-netflix-zuul</artifactId>

</dependency>

application.properties:

server.port=7005

spring.application.name=springboot-zuul-server

eureka.client.serviceUrl.defaultZone=http://register-server.sclouds.svc.cluster.local:8000/eureka/

zuul.stripPrefix=false

zuul.ignored-services="*"

zuul.routes.api-a.path=/ribbon/**

zuul.routes.api-a.serviceId=springboot-eureka-client

zuul.routes.api-a.strip-prefix=false

ribbon.eureka.enabled=true

eureka.instance.prefer-ip-address=true

注:這里設置一個路由規(guī)則,路由到springboot-eureka-client微服務(下文有例子)

Dockerfile:

FROM java:8

VOLUME /tmp

ADD ecurkazuul-0.0.1-SNAPSHOT.jar /ecurkazuul-0.0.1-SNAPSHOT.jar

ADD skagent /skagent

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/ecurkazuul-0.0.1-SNAPSHOT.jar"]

3.2.k8s service

Zuul集群實例不需要互相同步狀態(tài)瓦戚,部署Deployment即可沮尿。Service進行服務暴露負載

Yaml:

apiVersion: v1

kind: Service

metadata:

? name: ecurka-zuul

? namespace: sclouds

? labels:

? ? verison: "1.0.0"

? ? env: "test"

spec:

? type: NodePort

? selector:

? ? app: ecurka-zuul

? ? release: master

? ports:

? ? ? - name: http

? ? ? ? port: 7005

? ? ? ? targetPort: 7005

? ? ? ? nodePort: 30112

---

apiVersion: apps/v1

kind: Deployment

metadata:

? name: ecurka-zuul

? namespace: sclouds

? labels:

? ? verison: "1.0.0"

? ? env: "test"

spec:

? replicas: 2

? selector:

? ? matchLabels:

? ? ? app: ecurka-zuul

? ? ? release: master

? template:

? ? metadata:

? ? ? labels:

? ? ? ? app: ecurka-zuul

? ? ? ? release: master

? ? spec:

? ? ? containers:

? ? ? ? - name: ecurka-zuul

? ? ? ? ? image: dw/ecurka-zuul

? ? ? ? ? imagePullPolicy: IfNotPresent

? ? ? ? ? ports:

? ? ? ? ? ? - name: http

? ? ? ? ? ? ? containerPort: 7005

應用service,部署兩個pod實例:

pods

登錄ecureka较解,看到有兩個zuul服務實例在運行:


ecureka

4畜疾、SkyWalking

這里簡單介紹一下Windows單機部署

4.1.軟件版本

Skywalking 8.7.0

下載地址:https://skywalking.apache.org/downloads/

Elasticsearch 6.8.23

下載地址:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-8-23

本文選擇Elasticsearch 作為skywalking的數(shù)據(jù)庫,skywalking與el的版本需要對應印衔,如果使用Elasticsearch7啡捶,需要下載es后綴的skywalking版本。

4.2.elasticsearch

elasticsearch.yml修改:

4.3.Skywalking

分為兩個服務当编,后臺信息收集服務oap届慈,前端門戶ui(skywalking-webapp)

?OAP后臺服務

config:application.yml

選擇數(shù)據(jù)庫類型

?UI門戶工程

webapp.yml徒溪,如果端口被占用忿偷,可修改默認端口

webapp.yml


4.4.服務啟動

啟動Elasticsearch

執(zhí)行elasticsearch.bat,默認占用9200端口

啟動skywalking

執(zhí)行startup.bat臊泌,或者分別執(zhí)行oapService.bat鲤桥、webappService.bat,默認占用11800,12800,8080端口渠概。

4.5.Springboot工程接入

Skywalking對于Java工程是非侵入的茶凳,通過探針進行接口探測嫂拴,數(shù)據(jù)上報。只需要在啟動后臺服務時贮喧,加入啟動參數(shù)筒狠,指定Skywalking agent依賴包以及oap服務Url,idea中可在工程啟動配置中配置箱沦,有兩個屬性需要注意辩恼,skywalking.agent.service_name是skywalking中顯示的服務名稱,不同服務需要區(qū)分谓形。skywalking.collector.backend_service灶伊,是skywalking服務端的地址,要根據(jù)實際情況修改寒跳。本文中聘萨,skywalking沒有部署到k8s中,寫的是skywalking部署主機的地址童太。

參考:

-javaagent:J:\tmppro\demo\skagent\skywalking-agent.jar -Dskywalking.agent.service_name=DemoHelloService -Dskywalking.collector.backend_service=192.168.76.54:11800


idea java vm參數(shù)

HTTP調用米辐,Skywalking前端觀測


skywalking


4.6.springboot服務docker鏡像打包修改

拷貝skywalking agent依賴到docker鏡像打包目錄


docker打包目錄

修改Dockerfile,加入加粗字體部分:

FROM java:8

VOLUME /tmp

ADD ecurkaclient-0.0.1-SNAPSHOT.jar /ecurkaclient-0.0.1-SNAPSHOT.jar

ADD skagent /skagent

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-javaagent:/skagent/skywalking-agent.jar","-Dskywalking.agent.service_name=EurekaClient","-Dskywalking.collector.backend_service=192.168.76.54:11800","-jar","/ecurkaclient-0.0.1-SNAPSHOT.jar"]

5书释、服務實例


5.1.springboot鏡像

Java代碼儡循,設置兩個url作為服務實驗:

package com.example.ecurkaclient;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class TestController {

? ? private static final Logger log = LoggerFactory.getLogger(TestController.class);

? ? @RequestMapping(value = "/hello", method = RequestMethod.GET)

? ? public ResponseX testHello() {

? ? ? ? ResponseX x = new ResponseX();

? ? ? ? x.setMsg("hello-x");

? ? ? ? log.info("######################################\n" + "hello");

? ? ? ? return x;

? ? }

? ? @RequestMapping(value = "/helloworld", method = RequestMethod.GET)

? ? public ResponseX testHellox() {

? ? ? ? ResponseX x = new ResponseX();

? ? ? ? x.setMsg("hello-world-x");

? ? ? ? log.info("######################################\n" + "hello-world");

? ? ? ? return x;

? ? }

}

application.properties:

server.port=7004

spring.application.name=springboot-eureka-client

eureka.client.serviceUrl.defaultZone=http://register-server.sclouds.svc.cluster.local:8000/eureka/

eureka.instance.prefer-ip-address=true

注:spring.application.name和前面zuul網(wǎng)關設置的zuul.routes.api-a.serviceId要對應。Zuul網(wǎng)關根據(jù)服務名稱進行路由征冷。

Dockerfile打包鏡像:

FROM java:8

VOLUME /tmp

ADD ecurkaclient-0.0.1-SNAPSHOT.jar /ecurkaclient-0.0.1-SNAPSHOT.jar

ADD skagent /skagent

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-javaagent:/skagent/skywalking-agent.jar","-Dskywalking.agent.service_name=EurekaClient","-Dskywalking.collector.backend_service=192.168.76.54:11800","-jar","/ecurkaclient-0.0.1-SNAPSHOT.jar"]

5.2.k8s service

Yaml:

apiVersion: v1

kind: Service

metadata:

? name: ecurka-client

? namespace: sclouds

? labels:

? ? verison: "1.0.0"

? ? env: "test"

spec:

? selector:

? ? app: ecurka-client

? ? release: master

? ports:

? ? ? - name: http

? ? ? ? port: 7004

? ? ? ? targetPort: 7004

---

apiVersion: apps/v1

kind: Deployment

metadata:

? name: ecurka-client

? namespace: sclouds

? labels:

? ? verison: "1.0.0"

? ? env: "test"

spec:

? replicas: 2

? selector:

? ? matchLabels:

? ? ? app: ecurka-client

? ? ? release: master

? template:

? ? metadata:

? ? ? labels:

? ? ? ? app: ecurka-client

? ? ? ? release: master

? ? spec:

? ? ? containers:

? ? ? ? - name: ecurka-client

? ? ? ? ? image: dw/ecurka-client

? ? ? ? ? imagePullPolicy: IfNotPresent

? ? ? ? ? ports:

? ? ? ? ? ? - name: http

? ? ? ? ? ? ? containerPort: 7004

6择膝、日志采集(SkyWalking)

logback設置GRPCLogClientAppender,設置日志級別:

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

? ? <appender name="msystem-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">

? ? ? ? <!-- 日志輸出編碼 -->

? ? ? ? <encoder>

? ? ? ? ? ? <!--格式化輸出:%d表示日期检激,%thread表示線程名肴捉,%-5level:級別從左顯示5個字符寬度%msg:日志消息,%n是換行符-->

? ? ? ? ? ? <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>

? ? ? ? </encoder>

? ? </appender>

? ? <root level="info">

? ? ? ? <appender-ref ref="msystem-log"/>

? ? </root>

</configuration>

完成上述配置叔收,日志就會上傳到skywalking

log.info("######################################\n" + "hello-world");


skywalking日志界面
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末齿穗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子饺律,更是在濱河造成了極大的恐慌窃页,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件复濒,死亡現(xiàn)場離奇詭異脖卖,居然都是意外死亡,警方通過查閱死者的電腦和手機巧颈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門畦木,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人砸泛,你說我怎么就攤上這事十籍∏猓” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵勾栗,是天一觀的道長惨篱。 經(jīng)常有香客問我,道長围俘,這世上最難降的妖魔是什么妒蛇? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮楷拳,結果婚禮上绣夺,老公的妹妹穿的比我還像新娘。我一直安慰自己欢揖,他們只是感情好陶耍,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著她混,像睡著了一般烈钞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坤按,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天毯欣,我揣著相機與錄音,去河邊找鬼臭脓。 笑死酗钞,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的来累。 我是一名探鬼主播砚作,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嘹锁!你這毒婦竟也來了葫录?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤领猾,失蹤者是張志新(化名)和其女友劉穎米同,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摔竿,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡面粮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了拯坟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片但金。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖郁季,靈堂內(nèi)的尸體忽然破棺而出冷溃,到底是詐尸還是另有隱情,我是刑警寧澤梦裂,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布似枕,位于F島的核電站,受9級特大地震影響年柠,放射性物質發(fā)生泄漏凿歼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一冗恨、第九天 我趴在偏房一處隱蔽的房頂上張望答憔。 院中可真熱鬧,春花似錦掀抹、人聲如沸虐拓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蓉驹。三九已至,卻和暖如春揪利,著一層夾襖步出監(jiān)牢的瞬間态兴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工疟位, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瞻润,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓甜刻,卻偏偏與公主長得像敢订,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子罢吃,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

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