SpringCloud 服务注册和消费实现过程

系统架构

在没有微服务之前有已经有跨服务调用了,比如ServiceB去调用ServiceA中的服务 , 传统模式可以直接在ServiceB中写ServiceA中的服务但是这样是写死了的,不够灵活。

下图就是传统的调用

微服务下的跨系统调用应该是这样的:

此时服务的调用应该是分两个步骤的:
ServiceB 去服务中心拿到ServiceA的地址,如果ServiceA是单机部署,那么这个地址就只有一个,如果ServiceA是集群是集群环境部署,那么发现的地址就是多个。

拿到了ServiceA的地址后,ServiceB再去调用ServiceA的相关服务了。

这样做其实是有很多好处的,首先互相调用的地址可以不用写死,需要的时候直接去服务中心获取,并且服务之间也可以很方便的部署、集群等。

服务注册与消费搭建

1.首先我们创建一个ServiceRegister的普通maven项目,然后在创建一个Eureka的SpringBoot项目作为子项目

下面是Eureka项目的pom.xml 配置

<dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
      <scope>runtime</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

下面是application.yml 配置文件

# 别名
spring:
 application:
  name: eureka
#端口
server:
 port: 1111

# eureka config
eureka:
 client:
  register-with-eureka: false
  fetch-registry: false

注意 这里配置好了后需要在Eureka这个子项目的启动类上加入下面这个注解

@EnableEurekaServer

这个注解的意义是代表这个项目成为一个注册中心

2.创建一个Provider

创建一个叫Provider的SpringBoot项目作为子项目,pom.xml配置

<properties>
  <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  </dependency>
</dependencies>
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

下面是application.yml 配置文件

# 别名
spring:
 application:
  name: provider
#端口
server:
 port: 4001
# provider config
eureka:
 client:
  service-url:
   defaultZone: http://localhost:1111/eureka 

spring.application.name 是服务的名称,你可以理解成是别名,其他的服务调用的时候需要使用这个name来调用

server.port 是端口号

eureka.client.service-url.defaultZone 是这个服务需要注册到服务中心地址,这里需要注意的是,如果服务中心是一个集群,这里也可以只写服务中心的一个节点,eureka会自动集群对服务进行同步。

在微服务中,你的项目的pom.xml 中如果存在 spring-cloud-starter-netflix-eureka-client的依赖,并且提供了eureka注册中心的地址那么会默认注册到 Eureka Server 中。

然后我们在 provider 中提供一个简单的服务

@RestController
public class SayHelloController {
 @GetMapping("/sayHello")
 public String SayHello(String name) {
  return "sayHello" + name + "!";
 }
}

这样我们就创建好我们的服务提供者,并且提供了一个简单的服务接口了。

3.创建consumer

创建好了服务提供者,那么我们就来创建服务消费者consumer,创建一个SpringBoot的子项目工程 pom依赖如下

<dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

这个配置和provider 配置几乎是一样的,下面是consumer的application.yml 配置文件

# 别名
spring:
 application:
  name: consumer
#端口
server:
 port: 4002
# provider config
eureka:
 client:
  service-url:
   defaultZone: http://localhost:1111/eureka

唯一变了就是服务的名称。

配置好了后,我们在consumer的启动类中添加一个RestTemplate的实例,RestTemplate是Spring提供的一个Http请求工具,下面是这个RestTemplate实例的代码

@SpringBootApplication
public class ConsumerApplication {

  public static void main(String[] args) {
    SpringApplication.run(ConsumerApplication.class, args);
  }

  @Bean
  RestTemplate restTemplate() {
    return new RestTemplate();
  }
}

然后我们在consumer 中添加一个UserSayHelloController,在这里去调用provider 提供的服务。

@RestController
public class SayUserHelloController {
  @Autowired
  DiscoveryClient discoveryClient;
  @Autowired
  RestTemplate restTemplate;
  @GetMapping("/sayHello")
  public String hello(String name) {
    List<ServiceInstance> list = discoveryClient.getInstances("provider");
    ServiceInstance instance = list.get(0);
    String host = instance.getHost();
    int port = instance.getPort();
    String s = restTemplate.getForObject("http://" + host + ":" + port + "/hello?name={1}", String.class, name);
    return s;
  }
}

上面代码的意思是解释如下:

首先我们在这个Controller中注入了一个DiscoveryClient ,DiscoveryClient可以从Eureka或者从Consul上根据服务名查询一个服务的详细信息,注意DiscoveryClient是下面这个包中的

org.springframework.cloud.client.discovery.DiscoveryClient
@Autowired
 RestTemplate restTemplate;

RestTemplate 就是Spring 给我们提供用来发送Http请求的,这个大多数人应该都是知道的。

List<ServiceInstance> list = discoveryClient.getInstances("provider");

discoveryClient.getInstances 就是调用服务的名称,为什么用List去接受? 那是因为有可能provider 是单机部署 也有可能是集群部署,如果是集群部署的话,那么provider的实例就有多个

ServiceInstance 保存了provider 中 详细的信息、如主机地址、端口号、实例id等。ServiceInstance是一个接口,它有很多给实现类,我们本次的这个项目使用的是EurekaServiceInstance。

ServiceInstance instance = list.get(0);

因为我们只有一个provider 实例,所以我们就用list.get(0) 来获取实例了

获取主机地址

String host = instance.getHost();

获取端口号

int port = instance.getPort();

RestTemplate 的 getForObject 方法接收三个参数。第一个参数是请求地址,请求地址中的 {1} 表示一个参数占位符,第一个参数 String.class 表示返回的参数类型,第三个参数则是一个第一个占位符的具体值。

String s = restTemplate.getForObject("http://" + host + ":" + port + "/hello?name={1}", String.class, name);

最后我们返回这个s 就完成了consumer的编写

下面我们依次的启动Eureka(注册中心)和 服务提供者(provider) 以及 消费者(consumer)

然后在浏览器上输入:
localhost:4002/sayHello?name=jishu
结果如下图所示:

这样我们就顺利的从consumer 去调用了provider 的服务了

DiscoveryClient是哪里来的

归根结底 DiscoveryClient作用就是可以从Eureka 或者Consul 中查询服务的实例,不过DiscoveryClient就是一个接口而已,但是还是有一个实现类, 这个具体的实现类就是CompositeDiscovery,当我们的微服务启动的时候,就会在CompositeDiscoveryClientAutoConfiguration类中配置一个CompositeDiscovery的实例,下面这个就是大名鼎鼎的CompositeDiscoveryClientAutoConfiguration的源码

//这里就是DiscoveryClient的源码了
@Configuration
@AutoConfigureBefore(SimpleDiscoveryClientAutoConfiguration.class)
public class CompositeDiscoveryClientAutoConfiguration {

 //这里返回的是一个实例
	@Bean
	@Primary
	public CompositeDiscoveryClient compositeDiscoveryClient(
			List<DiscoveryClient> discoveryClients) {
		return new CompositeDiscoveryClient(discoveryClients);
	}

}

其实真正调用的是CompositeDiscoveryClient类中的discoveryClients 属性提供的 DiscoveryClient,而discoveryClients 属性默认集合中只有一条数据,就是EurekaDiscoveryClient,最终在EurekaDiscoveryClient类中,通过EurekaClient来获取一个微服务的实例信息了

总结

在不用微服务调用,服务之间的调用是相当繁琐的,并且地址是写死了,那么部署的话是非常的不方便,但是我们提供了注册中心的话,那么我们让服务注册到我们的注册中心中,然后在从注册中心去获取我们的服务信息,这样就有大大的好处,降低了调用的难度。

项目地址

github

到此这篇关于SpringCloud 服务注册和消费实现过程的文章就介绍到这了,更多相关SpringCloud 服务注册 消费内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springcloud干货之服务注册与发现(Eureka)

    使用Eureka实现服务治理 作用:实现服务治理(服务注册与发现) 简介:Spring Cloud Eureka是Spring Cloud Netflix项目下的服务治理模块.而Spring Cloud Netflix项目是Spring Cloud的子项目之一,主要内容是对Netflix公司一系列开源产品的包装,它为Spring Boot应用提供了自配置的Netflix OSS整合.通过一些简单的注解,开发者就可以快速的在应用中配置一下常用模块并构建庞大的分布式系统.它主要提供的模块包括:服务发

  • 详解springcloud之服务注册与发现

    本次分享的是关于springcloud服务注册与发现的内容,将通过分别搭建服务中心,服务注册,服务发现来说明:现在北京这边很多创业公司都开始往springcloud靠了,可能是由于文档和组件比较丰富的原因吧,毕竟是一款目前来说比较完善的微服务架构:本次分享希望能给大家带来好的帮助: Eureka服务中心 Provider注册服务 Consumer发现服务 Eureka服务中心高可用 Eureka服务中心 就我现在了解到并且用的比较多的注册中心有zookeeper和Eureka,我的上上篇文章分享

  • springCloud服务注册Eureka实现过程图解

    介绍 Eureka 是Netfix开发的,一个基于Rest服务的,服务注册与发现的组件. 主要包括两个组件:Eureka Server和Eureka Client Eureka Server:注册中心,提供服务注册与发现 Eureka Client:java客户端(通常就是微服务中的客户端和服务端) 上图简要描述了Eureka的基本架构,由3个角色组成: 1.Eureka Server(注册中心,相当于中介) 2.Service Provider(服务提供方,相当于房东) 3.Service C

  • SpringCloud之服务注册与发现Spring Cloud Eureka实例代码

    一.Spring Cloud简介 Spring Cloud是一个基千SpringBoot实现的微服务架构开发 工具.它为微服务架构中涉及的 配置管理.服务治理. 断路器. 智能路由.微代理. 控制总线. 全局锁. 决策竞选.分布式会话和集群状态管理等操作提供了一种简单的开发方式. Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品,还可能会新增),如下所述. Spring Cloud Config: 配置管理工具.Spring Cloud Netflix: 核心组件

  • SpringCloud Eureka实现服务注册与发现

    前言 Eureka是一种基于REST(具像状态传输)的服务,主要用于AWS云中定位服务,以实现中间层服务器的负载平衡和故障转移.本文记录一个简单的服务注册与发现实例. GitHub地址:https://github.com/Netflix/eureka 官网文档:https://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.1.0.RC2/single/spring-cloud-netflix.html Eureka-Ser

  • SpringCloud Eureka 服务注册实现过程

    一.将服务注册到Eureka 一个SpringBoot应用如果要注册到Spring Cloud环境(Greenwich.SR3版本),步骤很简单: pom.xml中添加启动器:spring-cloud-starter-netflix-eureka-client: 增加配置:eureka.client.serviceUrl.defaultZone: http://localhost:8100/eureka/: 启动应用: 如果注册中心正常,此时就能在注册中心发现这个应用了,如下图红框所示: 按照s

  • SpringCloud 服务注册和消费实现过程

    系统架构 在没有微服务之前有已经有跨服务调用了,比如ServiceB去调用ServiceA中的服务 , 传统模式可以直接在ServiceB中写ServiceA中的服务但是这样是写死了的,不够灵活. 下图就是传统的调用 微服务下的跨系统调用应该是这样的: 此时服务的调用应该是分两个步骤的: ServiceB 去服务中心拿到ServiceA的地址,如果ServiceA是单机部署,那么这个地址就只有一个,如果ServiceA是集群是集群环境部署,那么发现的地址就是多个. 拿到了ServiceA的地址后

  • SpringCloud 服务注册中的nacos实现过程

    如下图,org.springframework.cloud.spring-cloud-commons包下定义了一系列接口,其中就包括serviceregistry的系列规范,并通过SPI机制去调用接口实现. 在该包的META-INF/spring.factories文件中,可以找到EnableAutoConfiguration.class为key的value中有AutoServiceRegistrationAutoConfiguration.class这一项. 来看看这个AutoServiceR

  • dubbo服务注册到nacos的过程剖析

    目录 前言 简述过程 源码剖析具体实现 服务注册 服务订阅 结语 前言 前面聊到到了我们的dubbo服务从redis迁移到nacos注册中心,迁移后发现,会时不时的抛一个异常 ERROR com.alibaba.nacos.client.naming - [CLIENT-BEAT] failed to send beat:, 所以有了这个剖析过程,当然最后查明异常是我们的SLB网络映射问题,和nacos没有关系. dubbo版本:2.7.4.1 nacos client版本:1.0.0 naco

  • SpringCloud服务注册和发现组件Eureka

    本篇文章,我们来讲解springcloud的服务注册和发现组件,上一章节我们讲解了如何搭建springcloud的多模块项目,已经新建了springcloud-eureka-server,springcloud-eureka-client两个模块,本章节就在这基础上直接使用. 想要了解的请参考:一起来学Spring Cloud | 第一章 :如何搭建一个多模块的springcloud项目 一.Eureka简介: 1.1 什么是eureka Eureka是一个基于REST的服务,主要用于AWS云中

  • SpringCloud 服务注册IP错误的解决

    SpringCloud 服务注册IP错误 1.错误原因 在服务注册的时候,是使用 spring.cloud.client.ipAddress 这个变量,如果本机有多个网卡,那么可能会把不是本机以太网的网卡地址注册上去. 使用 ipconfig 可以看到,本机上有多个以太网适配器,而每个以太网适配器,都有一个 IPv4 地址,这时注册上去的 IP,就是其中一个,却不一定是正确的那个. 2.处理 2.1.禁用其他网卡 到电脑的 更改适配器 设置中,将不是本机以太网的其他网卡禁用 2.2.配置 到电脑

  • Springcloud服务注册consul客户端过程解析

    1.版本说明 springboot 2.2.5.RELEASE springcloud Hoxton.SR6 2.依赖 <!--引入consul client依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependen

  • Spring-cloud 服务发现与消费(以ribbon为例)

    说明: ribbon是spring-cloud中作为服务消费者的一种角色,客户端可以通过它来对服务提供者的服务进行消费, 比如本例中是服务提供者注册到注册中心,服务提供者提供了一个服务接口,返回一个hello字符串,我们通过ribbon将这个接口调用,再不暴露真实服务提供者的地址的同时,获取服务提供者的服务 前提: 按照之前几个教程,搭建出注册中心.服务提供者.这里可以使用分片的注册中心,也可以不使用,这里暂时定为使用之前搭好的分片注册中心,服务提供者仅提供一个即可. 准备工作: 1.启动注册中

随机推荐