public List getUpdatedListOfServers() {
//用namespace和serviceId做条件,得到该服务对应的所有节点(endpoints)信息
Endpoints endpoints = this.namespace != null
? this.client.endpoints().inNamespace(this.namespace)
List result = new ArrayList();
if (endpoints != null) {
if (LOG.isDebugEnabled()) {
LOG.debug(“Found [” + endpoints.getSubsets().size()
“] endpoints in namespace [” + this.namespace + “] for name [”
this.serviceId + “] and portName [” + this.portName + “]”);
}
//遍历所有的endpoint,取出IP地址和端口,构建成Server实例,放入result集合中
for (EndpointSubset subset : endpoints.getSubsets()) {
if (subset.getPorts().size() == 1) {
EndpointPort port = subset.getPorts().get(FIRST);
for (EndpointAddress address : subset.getAddresses()) {
result.add(new Server(address.getIp(), port.getPort()));
}
}
else {
for (EndpointPort port : subset.getPorts()) {
if (Utils.isNullOrEmpty(this.portName)
|| this.portName.endsWith(port.getName())) {
for (EndpointAddress address : subset.getAddresses()) {
result.add(new Server(address.getIp(), port.getPort()));
}
}
}
}
}
}
else {
LOG.warn(“Did not find any endpoints in ribbon in namespace [”
this.namespace + “] for name [” + this.serviceId
“] and portName [” + this.portName + “]”);
}
return result;
}
理论分析已经完成,接下来就开始实战吧
如果您不打算写代码,也可以从GitHub上下载本次实战的源码,地址和链接信息如下表所示:
| 名称 | 链接 | 备注 |
| :-- | :-- | :-- |
| 项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
| git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
| git仓库地址(ssh) | [email protected]:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
这个git项目中有多个文件夹,本章的Account-Service源码在spring-cloud-k8s-account-service文件夹下,Web-Service源码在spring-cloud-k8s-web-service文件夹下,如下图红框所示:
下面是详细的编码过程;
Account-Service服务是个很普通的springboot应用,和spring-cloud-kubernetes没有任何关系:
xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”> 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.1.RELEASE com.bolingcavalry account-service 0.0.1-SNAPSHOT account-service Demo project for Spring Cloud service provider run in kubernetes org.springframework.boot spring-boot-dependencies pom import ${spring-boot.version} org.springframework.boot spring-boot-starter ${springcloud.version} org.springframework.boot spring-boot-starter-web ${springcloud.version} org.springframework.boot spring-boot-maven-plugin ${spring-boot.version} repackage org.apache.maven.plugins maven-deploy-plugin ${maven-deploy-plugin.version} true org.apache.maven.plugins maven-surefire-plugin ${maven-surefire-plugin.version} true false io.fabric8 fabric8-maven-plugin ${fabric8.maven.plugin.version} fmp resource kubernetes io.fabric8 fabric8-maven-plugin ${fabric8.maven.plugin.version} fmp resource build NodePort 由上面的pom.xml内容可见,account-service应用是个简单的web应用,和SpringCloud、spring-cloud-kubernetes都没有任何关系,和其他springboot唯一的不同就是用到了fabric8-maven-plugin插件,可以方便的将应用部署到kubernetes环境; spring: application: name: account-service server: port: 8080 @RestController public class AccountController { private static final Logger LOG = LoggerFactory.getLogger(AccountController.class); private final String hostName = System.getenv(“HOSTNAME”); /** 探针检查响应类 @return */ @RequestMapping("/health") public String health() { return “OK”; } @RequestMapping("/") public String ribbonPing(){ LOG.info(“ribbonPing of {}”, hostName); return hostName; } /** 返回hostname @return 当前应用所在容器的hostname. */ @RequestMapping("/name") public String getName() { return this.hostName ", " new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”).format(new Date()); } } mvn clean install fabric8:deploy -Dfabric8.generator.from=fabric8/java-jboss-openjdk8-jdk -Pkubernetes 执行成功后控制台输出如下: … [INFO] Installing /usr/local/work/k8s/ribbon/spring-cloud-k8s-account-service/target/classes/META-INF/fabric8/kubernetes.json to /root/.m2/repository/com/bolingcavalry/account-service/0.0.1-SNAPSHOT/account-service-0.0.1-SNAPSHOT-kubernetes.json [INFO] [INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ account-service <<< [INFO] [INFO] [INFO] — fabric8-maven-plugin:3.5.37:deploy (default-cli) @ account-service — [INFO] F8: Using Kubernetes at https://192.168.121.133:8443/ in namespace default with manifest /usr/local/work/k8s/ribbon/spring-cloud-k8s-account-service/target/classes/META-INF/fabric8/kubernetes.yml [INFO] Using namespace: default [INFO] Updating a Service from kubernetes.yml [INFO] Updated Service: target/fabric8/applyJson/default/service-account-service.json [INFO] Using namespace: default [INFO] Updating Deployment from kubernetes.yml [INFO] Updated Deployment: target/fabric8/applyJson/default/deployment-account-service.json [INFO] F8: HINT: Use the command [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 11.941 s [INFO] Finished at: 2019-06-16T19:00:51+08:00 [INFO] ------------------------------------------------------------------------ [root@minikube spring-cloud-k8s-account-service]# kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE account-service 1/1 1 1 69m [root@minikube spring-cloud-k8s-account-service]# kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE account-service NodePort 10.105.157.201 8080:32596/TCP 69m kubernetes ClusterIP 10.96.0.1 443/TCP 8d [root@minikube spring-cloud-k8s-account-service]# minikube service account-service --url http://192.168.121.133:32596 可见account-service的服务可以通过这个url访问:http://192.168.121.133:32596 现在account-service服务已经就绪,接下来是开发和部署web-service应用。 Web-Service服务是个springboot应用,用到了spring-cloud-kubernetes提供的注册发现能力,以轮询的方式访问指定服务的全部pod: xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”> 4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.1.RELEASE com.bolingcavalry web-service 0.0.1-SNAPSHOT web-service Demo project for Spring Cloud service consumer run in kubernetes org.springframework.boot spring-boot-dependencies pom import ${spring-boot.version} org.springframework.cloud spring-cloud-kubernetes-core ${springcloud.kubernetes.version} org.springframework.cloud spring-cloud-kubernetes-discovery ${springcloud.kubernetes.version} org.springframework.cloud spring-cloud-starter-kubernetes-ribbon ${springcloud.kubernetes.version} org.springframework.cloud spring-cloud-commons ${springcloud.version} org.springframework.boot spring-boot-starter ${springcloud.version} org.springframework.boot spring-boot-starter-web ${springcloud.version} org.springframework.cloud spring-cloud-starter-netflix-ribbon ${springcloud.version} org.springframework.cloud spring-cloud-starter-netflix-hystrix ${springcloud.version} org.springframework.boot spring-boot-maven-plugin ${spring-boot.version} repackage org.apache.maven.plugins maven-deploy-plugin ${maven-deploy-plugin.version} true org.apache.maven.plugins maven-surefire-plugin ${maven-surefire-plugin.version} true false io.fabric8 fabric8-maven-plugin ${fabric8.maven.plugin.version} fmp resource kubernetes io.fabric8 fabric8-maven-plugin ${fabric8.maven.plugin.version} fmp resource build NodePort spring: application: name: web-service server: port: 8080 backend: ribbon: eureka: enabled: false client: enabled: true ServerListRefreshInterval: 5000 hystrix.command.BackendCall.execution.isolation.thread.timeoutInMilliseconds: 5000 hystrix.threadpool.BackendCallThread.coreSize: 5 package com.bolingcavalry.webservice; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AvailabilityFilteringRule; import com.netflix.loadbalancer.IPing; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.PingUrl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; /** @Description: ribbon配置类 @author: willzhao E-mail: [email protected] @date: 2019/6/16 11:52 */ public class RibbonConfiguration { @Autowired IClientConfig ribbonClientConfig; /** 检查服务是否可用的实例, 此地址返回的响应的返回码如果是200表示服务可用 @param config @return */ @Bean public IPing ribbonPing(IClientConfig config){ return new Pin 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》 【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享 gUrl(); } /** 轮询规则 @param config @return */ @Bean public IRule ribbonRule(IClientConfig config){ return new AvailabilityFilteringRule(); } } package com.bolingcavalry.webservice; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker @RibbonClient(name=“account-service”, configuration = RibbonConfiguration.class) public class WebServiceApplication { public static void main(String[] args) { SpringApplication.run(WebServiceApplication.class, args); } @LoadBalanced @Bean RestTemplate restTemplate(){ return new RestTemplate(); } }
kubectl get pods -w
to watch your pods start up
开发和部署Web-Service服务