SpringCloud 微服务
微服务是一种全新的架构风格。其优点主要有:
-
微服务把一个庞大的单体应用分解成一个个小型服务,比如图书管理系统,有登录、注册、搜索、借阅等功能,我们可以将这些姑奶奶单独做成一个小型的Spring Boot项目,独立运行。
-
每个小型的微服务,都可以独立部署和升级,这样即使系统崩溃,那么也只会影响一个服务的运行。
-
微服务之间使用HTTP进行数据交互,不再是但团体应用内部交互,这样虽然麻烦些,但带来的好处很多,不同的微服务可以使用不同的编程语言进行开发,只需要使用HTTP进行数据交互即可。
-
可以使用多台主机分别部署这些微服务,这样单机的压力分散到多台机器,而且每台的配置不需要很高,这样能节省成本,安全性也得到保证。
-
甚至一个微服务可以部署多个,这样当其中一个服务器出现问题时,其他服务器也在运行同样的服务。保证了服务的高可用。
但是微服务也存在很多问题:
- 实现微服务不是简单的将项目进行拆分,还要对各个微服务进行管理、监控等。这样才能及时地寻找和排查问题。因此微服务往往需要的时一套解决方案。包括服务注册与发现、容灾处理、负载均衡、配置管理等。
- 不方便维护。由于部署在多个服务器,不得不去保证各个微服务能够稳定运行,在管理难度上高于单体应用。
- 在分布式环境下,单体应用的某些功能可能会变得比较麻烦,比如分布式事务。
为了解决这些问题,所以需要应用SpringCloud:
SpringCloud是一条分布式解决方案,集合了一些开源产品,包括诸多组件,共同组成SpringCloud框架。并且利用SpringBoot的开发便利性巧妙的简化了分布式系统基础设施的开发,如服务发现注册、配置中学、消息总线、负载均衡、熔断机制、数据监控等,都可以利用SpringBoot的开发风格做到一键启动和部署。
- Eureka-实现服务质量(服务注册与发现),我们可以对所有的微服务进行集中管理,包括他们的运行状态、信息等。
- Ribbon-为服务之间相互调用提供负载均衡算法(已被SpringCloudLoadBalancer取代)
- Hystrix-断路器,保护系统,控制故障范围。类似于保险丝,当发生危险时能防止进一步的发展。
- Zuul-api网关、路由、负载均衡等多种作用,就像路由器一样,可能有多个设备都连接了路由器,但数据包要转发给谁则是由路由器在进行(已被SpringCloudGateWay取代)
- Config-配置管理,实现配置文件集中管理
Eureka 注册中心
对单体应用进行拆分之后,服务之间可以相互调用,但是这样部署和维护起来很麻烦,如果微服务端口或者地址发生大规模的改变,我们不得不修改调用代码。为了削弱这种服务之间的强关联性,我们需要借助注册中心来管理服务。
Eureka能自动注册并发现微服务,然后对服务的状态、信息进行集中管理这样当我们需要获取其他服务的信息时,只需要向Eureka进行查询就可以了。
如何使用Eureka?
-
先搭建一个Eureka服务器,创建一个新的maven模块,在父项目中加入Spring Cloud依赖,注意加在dependencyManagement标签里面
xml<dependencyManagement> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2025.0.1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> -
为eureka项目添加依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
-
添加项目启动类
java@SpringBootApplication @EnableEurekaServer public class AppEureka { public static void main( String[] args ) { SpringApplication.run(AppEureka.class, args); } } -
添加配置文件
yamlserver: port: 8888 eureka: # 修改客户端设置 client: # 由于我们是服务端角色,所以不需要获取服务端,改为false,默认是true fetch-registry: false # 暂时不需要将自己也注册到eureka register-with-eureka: false # 将eureka服务端指向自己 service-url: defaultZone: http://localhost:8888/eureka
5.然后启动服务,我用的是springboot3.5.11,springcloud2025.0.1,此时启动时会报错,需要在eureka项目中加入以下依赖解决报错问题:
xml
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>3.1.9</version><!-- 版本需与Spring Cloud兼容 -->
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>3.1.9</version>
</dependency>
-
启动后访问http://localhost:8888/ 地址
-
下来需要把服务注册到eureka,在对应的微服务模块里面引入如下依赖:
xml<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>-
给每个服务加入如下配置:
yamleureka: # 修改客户端设置 client: # 指向eureka服务端 service-url: defaultZone: http://localhost:8888/eureka- 然后启动服务,此时可以在eureka中发现这些服务
-
-
在服务的配置中配置服务名,然后重启服务,就会在eureka中显示服务名称
yamlspring: application: name: book-service
在服务启动后,每隔一段时间就会给eureka发送一次心跳包,这样eureka就能感知到服务是否处于正常运行状态。s
现在服务注册成功了,那怎么实现服务发现呢?
-
先将RestTemplate纳入spring容器管理,加入配置类:
java@Configuration public class BeanConfiguration { @Bean // 负载均衡 @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }- 重写业务方法,只修改调用地址,将原来的localhost:8101改成对应的服务名即可
java
@Service
public class BorrowServiceImpl implements BorrowService {
@Autowired
private BorrowMapper borrowMapper;
@Autowired
private RestTemplate restTemplate;
@Override
public BorrowDetail findBorrowById(int uid) {
List<Borrow> allByUid = borrowMapper.getAllByUid(uid);
// 获取用户信息 localhost:8101 改成服务名user-service
User user = restTemplate.getForObject("http://user-service/user/" + uid, User.class);
// 获取每本书的详细信息
List<Book> bookList = allByUid.stream().map(borrow -> restTemplate.getForObject("http://book-service/book/" + borrow.getBid(), Book.class))
.collect(Collectors.toList());
return new BorrowDetail(user, bookList);
}
}
这样就完成了服务调用。
如何将一个服务扩成多个实例,来实现负载均衡?
先进入edit configuration 窗口,将一个模块设置成多个服务。
然后启动eureka,然后启动这些服务,会发现user-service会出现2个实例
注册中心高可用
如果eureka服务器挂了怎么办?
我们可以搭建eureka集群,启动多个 eureka服务器,这样就算挂掉一个,其他的也还在运行,使得服务注册与发现正常使用。
搭建 eureka 集群步骤如下:
-
修改eureka服务端的配置文件,注意修改hosts文件(路径C:\Windows\System32\drivers\etc\hosts)
application-01.yml内容如下:
yamlserver: port: 8801 eureka: # 修改客户端设置 client: # 由于我们是服务端角色,所以不需要获取服务端,改为false,默认是true fetch-registry: false # 去掉register-with-eureka ,使自己也注册到其他eureka服务器,这样才能相互调用 #register-with-eureka: false # 将eureka服务端指向自己 service-url: defaultZone: http://eureka02:8802/eureka instance: #由于不支持多个localhost的eureka服务器,而且是本地测试环境,所以只要改主机名称 hostname: eureka01 spring: application: name: eureka-service
application-02.yml内容如下:
yaml
server:
port: 8802
eureka:
# 修改客户端设置
client:
# 由于我们是服务端角色,所以不需要获取服务端,改为false,默认是true
fetch-registry: false
# 去掉register-with-eureka ,使自己也注册到其他eureka服务器,这样才能相互调用
#register-with-eureka: false
# 将eureka服务端指向自己
service-url:
defaultZone: http://eureka01:8801/eureka
instance:
#由于不支持多个localhost的eureka服务器,而且是本地测试环境,所以只要改主机名称
hostname: eureka02
spring:
application:
name: eureka-service
hosts文件添加如下内容:
127.0.0.1 eureka01
127.0.0.1 eureka02
配置服务:
2.接着修改微服务配置,使其注册到多个eureka服务器:
yaml
eureka:
# 修改客户端设置
client:
# 指向eureka服务端
service-url:
defaultZone: http://localhost:8801/eureka,http://localhost:8802/eureka
效果如下:
此时就完成了eureka集群的搭建和使用。