当我们创建一个传统的SpringBoot项目,随着项目的不断扩大,越来越多的功能被加入到项目中,此时如果所有功能都集中到单端上,会对服务器造成巨大压力,一台服务器承受不住巨大的单体应用的部署,且单体应用维护也愈发困难,这就需要我们开发新的框架来解决了。
但其背后也存在许多问题:
而SpringCloud就是Spring提供的一套分布式解决方案。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、熔断机制、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
SpringCloud整体架构的亮点是非常明显的,分布式架构下的各个场景,都有对应的组件来处理,比如基于Netflix(奈飞)的开源分布式解决方案提供的组件:
Eureka
Eureka能够自动注册并发现微服务,然后对服务的状态、信息进行集中管理,这样当我们需要获取其他服务的信息(如服务请求地址)时,我们只需要向Eureka进行查询就可以了。
首先我们需要让项目支持SpringCloud,我们需要在父项目里引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
然后,我们需要创建一个新的maven项目作为Eureka服务器(记得创建启动类和xml配置文件),引入Eureka服务器依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
启动类需要在@SpringBootApplication注解下面加上@EnableEurekaServer注解表示作为Eureka服务器
之后我们需要修改application配置(这里使用yml):
server:
port: 8088
eureka:
# 开启之前需要修改一下客户端设置(虽然是服务端
client:
# 由于我们是作为服务端角色,所以不需要获取服务端,改为false,默认为true
fetch-registry: false
# 暂时不需要将自己也注册到Eureka
register-with-eureka: false
# 将eureka服务端指向自己
service-url:
defaultZone: http://localhost:8088/eureka
之后我们就可以通过这个端口来访问Eureka管理页面了。
如果存在端口访问失败,很有可能是SpringBoot版本依赖问题,更换SpringCloud版本即可
配置完服务器端,我们就可以去配置客户端了。
与服务器端类似,我们需要先导入客户端依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
之后我们需要修改配置文件:
eureka:
client:
# 跟上面一样,需要指向Eureka服务端地址,这样才能进行注册
service-url:
defaultZone: http://localhost:8088/eureka
之后,我们启动项目后,就能在Eureka管理页面看到注册进来的项目了。
但此时我们发现,这些项目在管理页面都还是UnKnown项目,这就需要我们在配置文件内添加项目名称:
spring:
application:
name: userservice
之后我们就能在管理页面看到项目(这里存在缓存,如果没重启服务器端则会依然显示几个Unknown)
当我们的服务启动之后,会每隔一段时间跟Eureka发送一次心跳包,这样Eureka就能够感知到我们的服务是否处于正常运行状态。
服务发现
在我们使用Eureka之前,如果需要几个项目相互调用接口,我们需要知道其准确的接口地址,而在较大项目中,很明显这个操作是难以维护的。而我们有了Eureka之后就能直接用服务名称向其进行查询,得到微服务地址。
此时,我们需要将RestTemplate(发起http请求的类)注册为bean来交由Spring管理,并添加@LoadBalance注解来让它支持按服务名称查询的同时,支持负载均衡。
由于bean的注册只能在启动类和配置类中,因此我们需要创建一个新的配置类:
@Configuration
public class BeanConfig {
@Bean
@LoadBalanced
RestTemplate template(){
return new RestTemplate();
}
}
这样,我们在需要使用其他项目接口的地方,注入这个bean,然后通过http://服务名称
就可以请求这个服务接口了。
说到负载均衡,我们需要知道在服务器上,一个Spring项目是可以开多个的,在IDEA的启动配置(编辑配置)内就可以添加:
我们可以通过加号,添加新的springboot项目,并配置名称与主类来实现
此时,我们需要配置两个项目的端口,我们首先把配置文件内端口删除,同时在编辑配置中的环境变量里添加端口:
这样我们就能运行两个相同的项目了。
那么接下来,运行两个相同项目有什么用呢?这就不得不提Eureka的作用。
当我们运行了两个相同的项目,我们会发现在管理页面,该项目的数量和地址数都增加了,这就代表,如果我们通过Eureka去查询接口,即使一个客户端断了,我们依然可以使用其他的地址去完成请求!
并且由于我们上面使用了@LoadBalance 注解实现负载均衡,在我们调用这个服务的时候,Eureka会使用轮询的方式进行请求,很大程度平摊了服务器压力。