现在越来越多人在讨论云原生,也就是使用Kubernetes作为部署架构,完全抽离IASS。其实Java跟云原生并不是这么搭配的,至少Spring Cloud跟Kubernetes 不合的,有很多功能重复的。 Spring Cloud的服务发现、配置中心、负载均衡、网关这些都可以在Kubernetes找到替代。我在想如果完全使用Kubernetes结构来处理分布式系统连接、发现、配置问题,剩下的服务器好像只有一个Spring Boot而已,不需要引入太多组件了。
简单构建两个微服务、让后将服务发现、注册中心这些组件统统抛弃,去使用Kubernetes去实现替代效果。使用pod 探针去检测微服务存过效果,完全是没有任何问题的。配置中心可以通过ConfigMap的卷挂载达到类似的效果,服务间的Fegin访问,可以不依赖服务发现进行,通过配置文件设定服务访问地址,访问地址再由Service进行维护,就可以达到屏蔽服务之间IP变化。其实很多人都很不屑为了这一点点性能,破坏整个完整Spring Cloud体系,但是我想的是,要Java往云原生发展,必须慢慢进行改变才行的,至少现在不能完全转向,量变促进质变。在云原生时代,对每一个服务有更高需要,更小的软件制品、更快的启动速度、更快执行速度,这些都要求在开发时尽量将每一个微服务技术依赖控制在一个可能小的范围。我的想法能不依赖就不依赖。减少微服务的技术依赖也有利于开发更容易参与进来,下面就可以行动吧。
项目编码
项目依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.3.RELEASE</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>${artifactId}</finalName>
</build>
下面只展示部分代码、feign客户端连接另一个服务
@FeignClient(name = "author",url = "${app.author.remote}")
public interface AuthorFeign {
@GetMapping("/author/getOne")
AuthorDTO getOne();
}
controller调用feign接口
@RestController
@RequestMapping("book")
public class BookController {
@Autowired
private AuthorFeign authorFeign;
@GetMapping("getOne")
public Book getOne(){
Book book = new Book();
return book;
}
@GetMapping("getAuthor")
public AuthorDTO getAuthor(){
return authorFeign.getOne();
}
}
application.yml配置文件
server:
port: 8080
spring:
application:
name: book
app:
author:
remote: localhost:8081
编译构建,Dockerfile
如下
FROM --platform=linux/amd64 docker.io/adoptopenjdk/openjdk8 AS java8
WORKDIR /opt/web
COPY target/book.jar .
ENV AUTHOR_URL author
ENTRYPOINT java -jar book.jar --app.author.remote}=${AUTHOR_URL} --server.port=80
进入book项目根路径, 执行命令构建镜像
docker build . -t book:1.0v
Kubernetes 配置
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: book-deployment
labels:
app: book
spec:
replicas: 1
selector:
matchLabels:
app: book
template:
metadata:
labels:
app: book
spec:
containers:
- name: book
image: book:1.0v
env:
- name: AUTHOR_URL
value: "author-clusterip"
ClusterIP配置
将服务端口暴露给集群内Pod访问
apiVersion: v1
kind: Service
metadata:
name: book-clusterip
spec:
type: ClusterIP
selector:
app: book
ports:
- name: http
port: 80
targetPort: 80
NodePort配置
将外部流量接入Pod
apiVersion: v1
kind: Service
metadata:
name: book-nodeport
spec:
type: NodePort
selector:
app: book
ports:
- name: book-http
port: 80
targetPort: 80
nodePort: 30001
如果有兴趣,去github看完整的项目cloud-demo
其实我对云原生Java应用也不是很了解,想听听大伙意见。
我从事Java快7年了,14年出的Java8,17年就已经开始使用Java8作为主力开发环境,想不到6年过来了,我依然还是在用Java8.其实Java的版本一直在更新,从来都没有使用过。没当市场出现新潮的技术,总想跃跃欲试,学了很多东西,也忘记了很多东西🤦。我总是告诉自己我还能学,实际上连工作快找不到了,真的迷茫了,不知道该往什么方向走了。