相信很多 Java 程序员都有从一个 2~3 人初创阶段的团队到百人规模技术团队的演变的经历,也会见证了技术栈和系统架构从传统到现代的变迁。
从最初使用的JSP,到如今前后端分离+SpringCloud的微服务架构。我们的技术、架构和运维模式经历了翻天覆地的变化。
随着公司的发展,老板钱多了想做大做强、招架构师、招总监、系统用户量大了等问题,所以系统需要升级,需要改造,那么必经之路就是微服务架构的应用。
微服务架构其实就是把一个大应用拆成一堆小服务。每个服务负责特定的功能,能独立开发和部署。这种做法有很多好处,比如灵活性强,团队可以用不同的技术栈,各自干各自的事;扩展起来也方便,某个服务需要更多资源时,可以单独扩展,不会影响整个系统。
微服务架构现在真的是越来越流行,很多开发者和企业都在使用。这种架构把应用拆分成多个小服务,每个服务专注于某个业务功能,能独立开发、部署和扩展。接下来,我就记录一下如何用Java和Spring Boot来实现服务的注册、发现和调用。
一、技术栈
在这个项目中,我们会用到以下技术:
- Java:编程语言。
- Spring Boot2.3.8:快速构建微服务的框架。
- Nacos:服务注册和发现工具。
- Feign:用于服务间的声明式调用。
- Spring Cloud:提供构建分布式系统的工具。
- Redis 5.0:缓存数据存储
- Mysql-plus:数据库脚手架
二、项目结构
我们将搭建几个模块:
三、实现步骤
1. 准备Nacos
首先,我们需要下载并启动Nacos。可以直接从官方GitHub上获取,按照说明启动Nacos服务器。
2. 创建微服务项目
接下来,我们创建两个微服务项目,分别为 auth(认证服务) 和 admin(用户管理服务) 。在这两个项目的pom.xml中,添加Spring Boot和Nacos的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
3. 配置Nacos
在application.yml文件中,为每个微服务配置Nacos的地址和服务名。以下是 admin 的配置示例:
spring:
application:
name: admin
cloud:
nacos:
discovery:
server-addr: http://localhost:8848
config:
server-addr: http://localhost:8848
file-extension: yaml
同样,admin 的配置也要类似,只需更改spring.application.name的值。
4. 创建服务
在 admin 中,提供了用户详细信息的接口/details/{username},controller 名称叫SysUserController:
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class SysUserController {
private final SysUserService sysUserService;
@GetMapping("/details/{username}")
public Result details(@PathVariable("username") String username) {
return Result.success(sysUserService.getUserDetailsByUsername(username));
}
@ApiOperation(value = "获取当前登录用户信息")
@GetMapping(value = "/info")
public Result getCurrentUserInfo(HttpServletRequest request) {
String userStr = request.getHeader(AuthConstants.AUTH_HEADER);
String username = (String) new JSONObject(userStr).get("user_name");
return Result.success(sysUserService.getUserDetailsByUsername(username));
}
@GetMapping("/list")
public Result listByPage() {
return Result.success(sysUserService.list());
}
}
在 auth 中,使用Feign来调用 admin 的接口。首先,创建Feign客户端:
@FeignClient(contextId = "remoteUserService",
value = ServiceConstants.ADMIN_SERVICE,
url = "http://localhost:8001")
public interface RemoteUserService {
/**
* 通过用户名查询用户、角色信息
* @param username 用户名
* @return R
*/
@GetMapping("/user/details/{username}")
Result<SysUserDetails> getUserDetailsByUsername(@PathVariable("username") String username);
}
然后在 auth 的 实现中调用这个Feign客户端:
private final RemoteUserService remoteUserService;
/**
* 用户密码登录
* @param username 用户名
* @return
*/
@Override
@SneakyThrows
public UserDetails loadUserByUsername(String username) {
Result<SysUserDetails> result = remoteUserService.getUserDetailsByUsername(username);
UserDetails userDetails = getUserDetails(result);
return userDetails;
}
这就是 springcloud 微服务的调用核心,
把项目需求拆分成多个微服务,微服务创造后注册到 nacos、eureka 等注册中心上,这让其它微服务就可以调它了。
当然微服务也可以使用统一的配置中心如 Nacos、Apollo 等。
微服务监控可以使用 SpringBootAdmin+Actuator微服务监控。
日志管理一般使用 ELK以实时监控服务状态。
当然微服务比较多的情况下,通常会采用 docker 进行部署,并使用 k8s 来进行管理。同时也会引入 Prometheus+Grafana 来监控与预警。