这是我参与更文挑战的第17天,活动详情查看:更文挑战。
今天主讲利用 k8s 来实现服务的注册与发现,甚至负载均衡,这在云原生时代又是一新型技术发展。
环境
-
ubuntu16.04
-
docker18.04
-
k8s1.13.x +
-
maven3.5.3
-
java1.8 +
-
springboot 2.1.1
-
spring-cloud-kubernetes:1.0.1.RELEASE
我们都知道,涉及到微服务,那必体现六个字,”高内聚,低耦合”,所以针对不同业务或应用场景,服务模块化很重要,这个不再赘述了。咱们先来创建服务提供方,同样,利用eclipse或IDEA创建一个项目,此处略了。
创建好项目之后,首先引入依赖:
<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>
复制代码
其他数据库,中间件等,可根据项目自行添加。
同样,我们需要配置初始化bean,这就涉及到配置文件bootstrap.yaml:
spring:
application:
name: demo-cas
cloud:
kubernetes:
discovery:
all-namespaces: true
复制代码
下面,我们看看application的配置:
server:
port: 1000
undertow:
accesslog:
enabled: false
pattern: combined
servlet:
session:
timeout: PT120M
复制代码
到这,基本的配置即完成,同样,我们也引入了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.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
复制代码
#这是针对所有的提供者服务的消费策略:
backend:
ribbon:
eureka:
enabled: false
client:
enabled: true
ServerListRefreshInterval: 5000
ribbon:
ConnectTimeout: 3000
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
复制代码
这样,服务提供者与服务消费者就都新建成功了,接下来就需要丰满自己的业务应用逻辑了,同样,消费者也可以创建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上,这里不贴截图了,大家可以试试。
上面分享的是通过service的方式提供了服务的注册与发现,而且单机的k8s本身也不重,所以操作起来也非常之简单。避免了springboot原生提供的eureka、阿里的nacos、zk来作分布式的服务注册与发现要简单的多。减轻系统的繁重,以及避免了系统的冗余。