





-
前端和後端緊密耦合——實際上它不能在沒有後端的情況下處理應用
-
前端和後端必須一致擴充套件——如果沒有足夠的後端,你可能會淹沒在流量中
-
如果後端不可用,則無法處理傳入的事務。

-
如果後端不可用,則佇列充當緩衝區
-
如果前端產生的訊息多於後端可以處理的訊息,則這些訊息將緩衝在佇列中
-
你可以獨立於前端擴充套件後端——即你可以擁有數百個前端服務和後端的單個實體
-
一個購買物品的主頁
-
管理面板,你可以在其中檢查佇列中的訊息數
-
一個 /health 端點,用於在應用程式準備好接收流量時發出訊號
-
一個 /submit 端點,從表單接收提交併在佇列中建立訊息
-
一個 /metrics 端點,用於公開佇列中待處理訊息的數量(稍後將詳細介紹)




@Componentpublic class QueueService implements MessageListener {private static final Logger LOGGER = LoggerFactory.getLogger(QueueService.class);@Autowiredprivate JmsTemplate jmsTemplate;public void send(String destination, String message) {LOGGER.info("sending message='{}' to destination='{}'", message, destination);jmsTemplate.convertAndSend(destination, message);}@Overridepublic void onMessage(Message message) {if (message instanceof ActiveMQTextMessage) {ActiveMQTextMessage textMessage = (ActiveMQTextMessage) message;try {LOGGER.info("Processing task " textMessage.getText());Thread.sleep(5000);LOGGER.info("Completed task " textMessage.getText());} catch (InterruptedException e) {e.printStackTrace();} catch (JMSException e) {e.printStackTrace();}} else {LOGGER.error("Message is not a text message " message.toString());}}}
@SpringBootApplication@EnableJmspublic class SpringBootApplication implements JmsListenerConfigurer {@Autowiredprivate QueueService queueService;public static void main(String[] args) {SpringApplication.run(SpringBootApplication.class, args);}@Overridepublic void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();endpoint.setId("myId");endpoint.setDestination("queueName");endpoint.setMessageListener(queueService);registrar.registerEndpoint(endpoint);}}
minikube start \--memory 8096 \--extra-config=controller-manager.horizontal-pod-autoscaler-upscale-delay=1m \--extra-config=controller-manager.horizontal-pod-autoscaler-downscale-delay=2m \--extra-config=controller-manager.horizontal-pod-autoscaler-sync-period=10s
minikube docker-env
docker build -t spring-k8s-hp0a .
docker images |grep spring
-
呈現前端的Spring Boot應用程式
-
ActiveMQ作為訊息代理
-
處理事務的Spring Boot後端
-
Deployment物件,描述部署的容器及其配置
-
一個Service物件,充當Deployment部署建立的應用程式的所有實體的負載均衡器

apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: queuespec:replicas: 1template:metadata:labels:app: queuespec:containers:- name: webimage: webcenter/activemq:5.14.3imagePullPolicy: IfNotPresentports:- containerPort: 61616resources:limits:memory: 512Mi
-
你從名為webcenter / activemq的官方倉庫中請求了一個activemq容器
-
容器在埠61616上公開訊息代理
-
為容器分配了512MB的記憶體
-
你要求提供單個副本 – 你的應用程式的單個實體
apiVersion: v1kind: Servicemetadata:name: queuespec:ports:- port: 61616targetPort: 61616selector:app: queue
-
你建立了一個公開埠61616的負載均衡器
-
傳入流量分發到所有具有app:queue型別標簽的Pod(請參閱上面的部署)
-
targetPort是Pod暴露的埠
kubectl create -f activemq-deployment.yamlkubectl create -f activemq-service.yaml
kubectl get pods -l=app=queue
apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: frontendspec:replicas: 1template:metadata:labels:app: frontendspec:containers:- name: frontendimage: spring-boot-hpaimagePullPolicy: IfNotPresentenv:- name: ACTIVEMQ_BROKER_URLvalue: "tcp://queue:61616"- name: STORE_ENABLEDvalue: "true"- name: WORKER_ENABLEDvalue: "false"ports:- containerPort: 8080livenessProbe:initialDelaySeconds: 5periodSeconds: 5httpGet:path: /healthport: 8080resources:limits:memory: 512Mi
-
有一個section可以註入環境變數
-
還有Liveness探針,可以告訴你應用程式何時可以接受流量
apiVersion: v1kind: Servicemetadata:name: frontendspec:ports:- nodePort: 32000port: 80targetPort: 8080selector:app: frontendtype: NodePort
kubectl create -f fe-deployment.yamlkubectl create -f fe-service.yaml
kubectl get pods -l=app=frontend
apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: backendspec:replicas: 1template:metadata:labels:app: backendannotations:prometheus.io/scrape: 'true'spec:containers:- name: backendimage: spring-boot-hpaimagePullPolicy: IfNotPresentenv:- name: ACTIVEMQ_BROKER_URLvalue: "tcp://queue:61616"- name: STORE_ENABLEDvalue: "false"- name: WORKER_ENABLEDvalue: "true"ports:- containerPort: 8080livenessProbe:initialDelaySeconds: 5periodSeconds: 5httpGet:path: /healthport: 8080resources:limits:memory: 512Mi
apiVersion: v1kind: Servicemetadata:name: backendspec:ports:- nodePort: 31000port: 80targetPort: 8080selector:app: backendtype: NodePort
kubectl create -f backend-deployment.yamlkubectl create -f backend-service.yaml
kubectl get pods -l=app=backend
minikube service backend
minikube service frontend
-
你可以手動放大和縮小
-
你可以建立自動縮放規則以自動向上或向下擴充套件
kubectl scale --replicas=5 deployment/backend
kubectl get pods
kubectl scale --replicas=1 deployment/backend
# HELP messages Number of messages in the queue# TYPE messages gaugemessages 0
cd spring-boot-k8s-hpa/monitoring
kubectl create -f ./metrics-serverkubectl create -f ./namespaces.yamlkubectl create -f ./prometheuskubectl create -f ./custom-metrics-api
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq .
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/messages" | jq .
apiVersion: autoscaling/v2beta1kind: HorizontalPodAutoscalermetadata:name: spring-boot-hpaspec:scaleTargetRef:apiVersion: extensions/v1beta1kind: Deploymentname: backendminReplicas: 1maxReplicas: 10metrics:- type: Podspods:metricName: messagestargetAverageValue: 10
-
Kubernetes監視scaleTargetRef中指定的部署。在這種情況下,它是工人。
-
你正在使用messages指標來擴充套件你的Pod。當佇列中有超過十條訊息時,Kubernetes將觸發自動擴充套件。
-
至少,部署應該有兩個Pod。10個Pod是上限。
kubectl create -f hpa.yaml
kubectl describe hpa
kubectl describe hpa
MAX(CURRENT_REPLICAS_LENGTH * 2, 4)

-
https://github.com/learnk8s/spring-boot-k8s-hpa
-
https://github.com/learnk8s/spring-boot-k8s-hpa/blob/master/src/main/java/com/learnk8s/app/queue/QueueService.java
-
https://kubernetes.io/docs/tasks/tools/
-
https://learnk8s.io/blog/installing-docker-and-kubernetes-on-windows
-
https://docs.docker.com/install/
-
https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler#deployment
知識星球