资讯专栏INFORMATION COLUMN

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

IT那活儿 / 1470人阅读
基于Spring boot2服务注册发现与调用

在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于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文件

org.springframework.boot

spring-boot-starter-parent

2.0.6.RELEASE

org.springframework.cloud

spring-cloud-dependencies

Finchley.SR1

pom

import

org.springframework.cloud

spring-cloud-starter-netflix-eureka-server

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

org.springframework.boot

spring-boot-starter-parent

2.1.12.RELEASE

com.shsnc

snc-base-service

1.0

snc-base-service

snc-base-service

org.springframework.cloud

spring-cloud-dependencies

Greenwich.SR5

pom

import



  org.springframework.cloud

  spring-cloud-starter-openfeign


  org.springframework.cloud

  spring-cloud-starter-netflix-eureka-client

上面的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();

ListuserList = new ArrayList();

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文件


com.shsnc

snc-kanban-service

1.0

snc-kanban-service

snc-kanban-service


org.springframework.boot

spring-boot-starter-parent

2.1.2.RELEASE


org.springframework.cloud

spring-cloud-dependencies

Greenwich.SR5

pom

import

org.springframework.cloud

spring-cloud-starter-openfeign

org.springframework.cloud

spring-cloud-starter-netflix-eureka-client


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. 如果本地缓存数据错误,请求到了错误的实例,本地缓存将会失效,并重新请求服务发现代理的数据。


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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/130165.html

相关文章

  • 《 Kotlin + Spring Boot : 下一代 Java 服务端开发 》

    摘要:下一代服务端开发下一代服务端开发第部门快速开始第章快速开始环境准备,,快速上手实现一个第章企业级服务开发从到语言的缺点发展历程的缺点为什么是产生的背景解决了哪些问题为什么是的发展历程容器的配置地狱是什么从到下一代企业级服务开发在移动开发领域 《 Kotlin + Spring Boot : 下一代 Java 服务端开发 》 Kotlin + Spring Boot : 下一代 Java...

    springDevBird 评论0 收藏0
  • Docker Swarm集群初探

    摘要:既然要组集群那就涉及诸如的资源调度管理等等一系列问题。目前涉及集群的三个主要的技术无外乎三种。从本文开始作者将会一一实践这几种主要的集群技术,话不多说,现在开始。完全运行于内存中,体积小,启动快。 showImg(https://segmentfault.com/img/remote/1460000015723680); 前言 相信Docker技术大家都有所了解,单个Docker能发...

    MingjunYang 评论0 收藏0
  • Spring Boot2(二):使用Spring Boot2集成Mybatis缓存机制

    摘要:本文章的源码再文章末尾什么是查询缓存有一级缓存和二级缓存。默认开启一级缓存。证明了一级缓存只是在数据库会话内部共享的。但是,整合到中后,一级缓存就会被关闭。根据时间表比如没有刷新间隔缓存不会以任何时间顺序来刷新。 仓库地址:spring-boot-learning欢迎star、fork,给作者一些鼓励 学习SpringBoot集成Mybatis的第二章,了解到Mybatis自带的缓存机...

    mikasa 评论0 收藏0
  • Spring Boot2(二):使用Spring Boot2集成Mybatis缓存机制

    摘要:本文章的源码再文章末尾什么是查询缓存有一级缓存和二级缓存。默认开启一级缓存。证明了一级缓存只是在数据库会话内部共享的。但是,整合到中后,一级缓存就会被关闭。根据时间表比如没有刷新间隔缓存不会以任何时间顺序来刷新。 仓库地址:spring-boot-learning欢迎star、fork,给作者一些鼓励 学习SpringBoot集成Mybatis的第二章,了解到Mybatis自带的缓存机...

    NSFish 评论0 收藏0
  • Spring Boot2(三):使用Spring Boot2集成Redis缓存

    摘要:本文章的源码再文章末尾什么是查询缓存有一级缓存和二级缓存。默认开启一级缓存。证明了一级缓存只是在数据库会话内部共享的。但是,整合到中后,一级缓存就会被关闭。根据时间表比如没有刷新间隔缓存不会以任何时间顺序来刷新。 学习SpringBoot集成Mybatis的第二章,了解到Mybatis自带的缓存机制,在部署的时候踩过了一些坑。在此记录和分享一下Mybatis的缓存作用。 本文章的源码再...

    NusterCache 评论0 收藏0

发表评论

0条评论

IT那活儿

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<