暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

基于Spring boot2服务注册发现与调用

IT那活儿 2020-08-27
1103

在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于httprestful的。Springcloud有两种服务调用方式,一种是ribbon+restTemplate模式,另一种是feign模式:

  • Ribbon+RestTemplate

Ribbon是一个基于HTTP和TCP客户端的负载均衡的工具。它可以 在客户端 配置RibbonServerList(服务端列表),使用HttpClient或RestTemplate模拟http请求,步骤比较繁琐。

  • Feign

Feign是在Ribbon的基础上进行了一次改进,是一个使用起来更加方便的HTTP客户端。采用接口的方式,只需要创建一个接口,然后在上面添加注解即可,将需要调用的其他服务的方法定义成抽象方法即可,不需要自己构建 http请求。然后就像是调用自身工程的方法调用,而感觉不到是调用远程方法,使得编写客户端变得非常容易。 

Feign和RestTemplate都内置了Ribbon

创建Eureka注册中心

在SpringCloud中,有多个组件可以起到服务发现代理的作用,但一般比较常用、较专业、可用性较高的是Eureka,Eureka分为Server和Client,Server是注册中心,Client是注册/调用方,接下来我们构建EurekaServer来启动一个服务发现代理。

1.创建一个maven项目,在pom.xml添加依赖jar文件

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.0.6.RELEASE</version>

</parent>

<dependencyManagement>

<dependencies>

<!--导入SpringCloud的依赖管理-->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>Finchley.SR1</version>

<type>pom</type>

<scope>import</scope>

</dependency>

</dependencies>

</dependencyManagement>

<dependencies>

<!--springboot整合eureka服务端-->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>

</dependency>

</dependencies>

2.创建application.yml文件

接下来,需要创建src/main/resources/application.yml文件(或application.properties,两者作用是一样的,但.yml文件为树形结构,更容易理解)。添加如下配置:

###服务端口号

server:

port:1011

###服务名称

spring:

application:

name:app-eureka-center

eureka:

instance:

#注册中心地址

hostname:192.168.199.101

###客户端调用地址

client:

serviceUrl:

defaultZone:http://192.168.199.101:1011/eureka/

###是否将自己注册到Eureka服务中,因为该应用本身就是注册中心,不需要再注册自己(集群的时候为true)

register-with-eureka:false

###是否从Eureka中获取注册信息,因为自己为注册中心,不会在该应用中的检索服务信息

fetch-registry:false

server:

enable-self-preservation:true

3.创建服务启动类

这一步是在启动类中添加@EnableEurekaServer注解,就可以让此应用程序成为一个Eureka服务。

@SpringBootApplication

@EnableEurekaServer//申明这是一个Eureka服务

publicclass SncApplication {

publicstatic void main(String[] args) {

SpringApplication.run(SncApplication.class,args);

}

}

4.项目结构图

5.测试访问Eureka注册中心

如上图显示,注册中心已搭建成功

创建服务提供者

1.创建一个maven项目,在pom.xml中导入依赖jar

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.1.12.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<groupId>com.shsnc</groupId>

<artifactId>snc-base-service</artifactId>

<version>1.0</version>

<name>snc-base-service</name>

<description>snc-base-service</description>

<dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>Greenwich.SR5</version>

<type>pom</type>

<scope>import</scope>

</dependency>

</dependencies>

</dependencyManagement>

<dependency>

  <groupId>org.springframework.cloud</groupId>

  <artifactId>spring-cloud-starter-openfeign</artifactId>

</dependency>

<dependency>

  <groupId>org.springframework.cloud</groupId>

  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

上面的pom文件为非完整版,只把其中的重要配置贴出来了

2.创建application.properties文件

在src/main/java/resources/application.yml创建如下配置:

spring.application.name=base-user-center

server.port=10011

eureka.client.serviceUrl.defaultZone=http://192.168.199.101:1011/eureka/

3.创建UserController接口

@RestController

@RequestMapping("/user")

publicclass UserController {

@RequestMapping("/getUserList")

@ResponseBody

publicModelMap getUserList() {

ModelMapmodelMap = new ModelMap();

List<String>userList = new ArrayList<String>();

userList.add("用户1");

userList.add("用户2");

userList.add("用户3");

modelMap.put("data",userList);

returnmodelMap;

}

}

4.创建启动类

@SpringBootApplication

@EnableFeignClients

@EnableEurekaClient

publicclass SncApplication {

publicstatic void main(String[] args) {

SpringApplication.run(SncApplication.class,args);

}

}

5.测试服务是否正常 

如上图显示,接口服务正常

6.在eureka注册中心上的效果

在这个demo中,我创建了一个名叫base-user-center的服务,在启动后,可以在Eureka管理界面看到该服务。

可以看到本地启动的base-user-center服务已经注册成功

创建服务消费者

服务注册成功后,我们可以使用另外的服务客户端来查找和调用该服务base-user-center,而不用知道该服务的位置。现在我们创建另一个服务,让这两个服务互相调用。

为了实现这个目的,我们需要引入客户端库。能够实现服务查找和调用功能的在SpringCloud中有三个客户端,分别为:

  • Spring DiscoveryClient.

  • RestTemplate

  • Netflix Feign

下面我们使用Feign来实现服务调用。

1.创建一个maven项目,在pom.xml中导入依赖jar文件

<groupId>com.shsnc</groupId>

<artifactId>snc-kanban-service</artifactId>

<version>1.0</version>

<name>snc-kanban-service</name>

<description>snc-kanban-service</description>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.1.2.RELEASE</version>

</parent>

<dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>Greenwich.SR5</version>

<type>pom</type>

<scope>import</scope>

</dependency>

</dependencies>

</dependencyManagement>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-openfeign</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

</dependency>

2.创建application.properties文件

spring.application.name=snc-kanban-service

server.port=30006

eureka.client.serviceUrl.defaultZone=http://192.168.199.101:1011/eureka/

3.创建feign客户端接口

我们通过@FeignClient注解来标志服务,其中的name为在Eureka中注册的应用ID。在这个接口中的send方法中,我们加上@RequestMapping注解来将此方法的实现映射到url。参数的传递通过@PathVariable注解将接口参数映射到url参数。远程接口的返回值将自动映射到接口返回值。

@FeignClient(name= "BASE-USER-CENTER")

publicinterface UserService {

@RequestMapping(value= "/user/getUserList")

publicModelMap getUserList();

}

4.创建消费者接口

@RestController

@RequestMapping("/order")

publicclass OrderController {

@Autowired

UserServiceuserService;

@RequestMapping("/getUserList")

publicModelMap getUserList() {

returnuserService.getUserList();

}

5.创建启动类

@SpringBootApplication

@EnableEurekaClient

@EnableFeignClients

publicclass SncApplication {

publicstatic void main(String[] args) {

SpringApplication.run(SncApplication.class,args);

}

}

6.测试消费者调用服务提供者接口

如上图所示,消费者成功调用了服务者提供的接口

实际应用及可用性保证机制

在上面的过程中,我们构建了一整个服务注册发现调用流程,在其中可以发现很多问题,比如Eureka挂掉怎么办,客户端联系不上Eureka怎么办,似乎这样的架构是非常脆弱的,但SpringCloud提供了一系列的机制来保证可用性,下面来进行分析。

1.服务发现集群

每个服务实例启动时会通过一个或多个服务发现代理进行注册它们的IP等信息,但即使只在一个服务发现节点注册。由于服务发现代理间使用了数据传播的点对点模型,每个节点的数据都会同步到服务发现集群中的所有节点。

在注册成功后,每个服务实例会按时间间隔发送心跳包,来推送自身的状态,一段时间没有发送心跳包时,会被从服务实例池中移除。

通过这样的方式,即使单个服务发现代理节点宕机,其他节点也能继续提供同样的服务。

2.客户端负载均衡

上图是加入了客户端缓存和负载均衡,和直接请求服务发现代理相比,进行了如下优化:

  1. 首先请求服务发现代理,获取它请求的服务的所有实例,并在本地进行缓存。

  2. 当需要调用该服务时,首先从缓存中查找所有实例信息,再使用负载均衡算法,选择一个实例进行调用。

  3. 客户端将定期请求服务发现代理,刷新缓存数据。

  4. 如果本地缓存数据错误,请求到了错误的实例,本地缓存将会失效,并重新请求服务发现代理的数据。

通过以上的机制,能最大程度地保证客户端能够正确地查找到所需服务的实例信息。

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论