好久没写文章了,本文继续上一篇,利用k8s来实现服务的注册与发现,甚至负载均衡,简称LB,完美无坑版!
环境:
ubuntu16.04
docker18.04
k8s1.13.x +
maven3.5.3
java1.8 +
springboot 2.1.1
spring-cloud-kubernetes:1.0.1.RELEASE

Relax
1. 前提
Ubuntu下安装docker18.04 or 其它较高版本,k8s1.13.x及以上,jvm环境等。
2. 创建项目
我们都知道,涉及到微服务,那必体现六个字,"高内聚,低耦合",所以针对不同业务或应用场景,服务模块化很重要,这个不再赘述了。咱们先来创建服务提供方,同样,利用eclipse或IDEA创建一个项目,此处略了。
创建好项目之后,首先引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
其他数据库,中间件等,可根据项目自行添加。
同样,我们需要配置初始化bean,这就涉及到配置文件bootstrap.yaml:
# we enable some of the management endpoints to make it possible to restart the application
management:
endpoint:
restart:
enabled: true
health:
enabled: true
info:
enabled: true
spring:
application:
name: edge-cas
cloud:
kubernetes:
reload:
#自动更新配置的开关设置为打开
enabled: true
#更新配置信息的模式:polling是主动拉取,event是事件通知
mode: event
#主动拉取的间隔时间是500毫秒
#period: 500
config:
sources:
- name: ${spring.application.name}
namespace: default
discovery:
all-namespaces: true
http:
encoding:
charset: UTF-8
enabled: true
force: true
mvc:
throw-exception-if-no-handler-found: true
main:
allow-bean-definition-overriding: true # 当遇到同样名称时,是否允许覆盖注册
接下来就是application.yaml:
server:
port: 1000
undertow:
accesslog:
enabled: false
pattern: combined
servlet:
session:
timeout: PT120M
logging:
path: /data/${spring.application.name}/logs
client:
http:
request:
connectTimeout: 8000
readTimeout: 30000
mybatis:
mapperLocations: classpath:mapper/*.xml
typeAliasesPackage: com.gemantic.*.model
到这,基本的配置即完成,同样,我们也引入了k8s的configmap功能,可以新建configmap的yaml文件来创建其configmap。
然后最重要的一点,就是我们需要创建service:
apiVersion: v1
kind: Service
metadata:
name: demo-cas-service
namespace: default
spec:
ports:
- name: cas01
port: 1000
targetPort: cas01
selector:
app: demo-cas
这一点很关键,即实现了服务的注册。
然后服务提供者的项目架子搭建好了,自己可以添加一些内容,比如我把它作为微服务架构的统一鉴权中心CAS。
接下来创建服务消费者的项目,同样引入依赖,但这一次不同:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>io.kubernetes</groupId>
<artifactId>client-java</artifactId>
<version>${kubernetes-client-version}</version>
<exclusions>
<exclusion>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- springcloud-k8s-discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
以上是服务消费者的必须依赖,其他的可根据项目自行添加,比如:在线文档swagger,数据库,json解析,权限管理shiro等。
同样,我们也需要配置初始化bean,这就涉及到配置文件bootstrap.yaml:如上
接下来需要配置服务消费者的消费逻辑以及实现负载均衡的策略(application.yaml):
server:
port: 1002
undertow:
accesslog:
enabled: false
pattern: combined
servlet:
session:
timeout: PT120M
logging:
path: /data/${spring.application.name}/logs
client:
http:
request:
connectTimeout: 8000
readTimeout: 30000
mybatis:
mapperLocations: classpath:mapper/*.xml
typeAliasesPackage: com.gemantic.*.model
#这是针对所有的提供者服务的消费策略:
backend:
ribbon:
eureka:
enabled: false
client:
enabled: true
ServerListRefreshInterval: 5000
ribbon:
ConnectTimeout: 3000
# 设置全局默认的ribbon的读超时
ReadTimeout: 1000
eager-load:
enabled: true
clients: demo-cas-service,cloud-admin-service
MaxAutoRetries: 1 #对第一次请求的服务的重试次数
MaxAutoRetriesNextServer: 1 #要重试的下一个服务的最大数量(不包括第一个服务)
#listOfServers: localhost:5556,localhost:5557
#ServerListRefreshInterval: 2000
OkToRetryOnAllOperations: true
NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RoundRobinRule
#这个是针对某个指定服务来进行配置负载均衡的策略
#demo-cas-service:
# ribbon:
# ConnectTimeout: 3000
# ReadTimeout: 60000
# MaxAutoRetries: 1 #对第一次请求的服务的重试次数
# MaxAutoRetriesNextServer: 1 #要重试的下一个服务的最大数量(不包括第一个服务)
# listOfServers: localhost:5556,localhost:5557
# ServerListRefreshInterval: 2000
# OkToRetryOnAllOperations: true
#NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RoundRobinRule
hystrix.command.BackendCall.execution.isolation.thread.timeoutInMilliseconds: 5000
hystrix.threadpool.BackendCallThread.coreSize: 5
这样,服务提供者与服务消费者就都新建成功了,接下来就需要丰满自己的业务应用逻辑了,同样,消费者也可以创建configmap来配置管理自己的配置。
接下来就是亲测:
这里,消费者调用提供者,提供者是个cas服务,则:
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("username", username);
map.add("password", password);
logger.info("CAS URL: {}", envConfig.getCas_url());
String respBody = HttpRequestUtil.doPostForm(restTemplate, envConfig.getCas_url(), map);
if (StringUtils.isNotBlank(respBody)) {
JSONObject pobj = JSON.parseObject(respBody);
Object object = pobj.get("message");
Integer code = JSON.parseObject(object.toString()).getInteger("code");
if (code == LoginEnum.LOGIN_SUCCESS.getSeq()) {
Object data = pobj.get("data");
SysUserDto sysUser = JSON.parseObject(data.toString(), SysUserDto.class);
return sysUser;
}
}
这里的环境变量即使configmap提供,值:cas_url: http://demo-cas-service/login,这样我们就完成了调用的逻辑。
亲测有效:

接下来我们如果需要测试LB,需要添加一条脚本:
增加pod:
kubectl scale --replicas=2 deployment demo-cas-deployment
这样,我们既看到两个demo-cas-deployment的pod:
同样测试,根据策略轮询调用的方式,这次会请求到该pod上,这里不贴截图了,大家可以试试。
以上,即是分享了k8s带来的第二大优点:
通过service的方式提供了服务的注册与发现,而且单机的k8s本身也不重,所以操作起来也非常之简单。避免了springboot原生提供的eureka、阿里的nacos、zk来作分布式的服务注册与发现要简单的多。减轻系统的繁重,以及避免了系统的冗余。
好了,以上即结束了本次分享,看完实践后觉得还可以,可以给小编一点激励,点个赞,谢谢!
个人网站:http://www.damon8.cn
本文介绍如何利用Kubernetes(k8s)实现Spring Cloud服务的注册与发现,包括配置服务提供方和消费方,使用配置中心,并演示负载均衡的设置和测试。
144

被折叠的 条评论
为什么被折叠?



