基于SpringCloud的服务注册和调用
一:服务的注册和发现
Eureka是Netflix开源的一款提供服务注册和发现的产品,它提供了完整的Service Registry(注册登记)和Service Discovery(发现)实现。也是springcloud体系中最重要最核心的组件之一。
服务中心:
服务中心又称注册中心,管理各种服务功能包括服务的注册、发现、熔断、负载、降级等。
有了服务中心调用关系会有什么变化,画几个简图来帮忙理解
例如:项目A调用项目B
正常调用项目A请求项目B

有了服务中心之后,任何一个服务都不能直接去掉用,都需要通过服务中心来调用

项目A调用项目B,项目B在调用项目C

这时候调用的步骤就会为两步:第一步,项目A首先从服务中心请求项目B服务器,然后项目B在从服务中心请求项目C服务。

上面的例子只是两三个项目之间相互简单的调用,但是如果项目超过20个30个呢,画一张图来描述几十个项目之间的相互调用关系全是线条,任何其中的一个项目改动,就会牵连好几个项目跟着重启,巨麻烦而且容易出错。通过服务中心来获取服务你不需要关注你调用的项目IP地址,由几台服务器组成,每次直接去服务中心获取可以使用的服务去调用既可。
由于各种服务都注册到了服务中心,就有了去做很多高级功能条件。比如几台服务提供相同服务来做均衡负载;监控服务器调用成功率来做熔断,移除服务列表中的故障点;监控服务调用时间来对不同的服务器设置不同的权重等等。
Eureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用作服务注册服务器。Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。

上图简要描述了Eureka的基本架构,由3个角色组成:
1、Eureka Server
- 提供服务注册和发现
2、Service Provider
- 服务提供方
- 将自身服务注册到Eureka,从而使服务消费方能够找到
3、Service Consumer
- 服务消费方
- 从Eureka获取注册服务列表,从而能够消费服务
二:创建注册中心 Eureka Server
创建一个简单的maven springboot项目
pom里面添加如下依赖:
1 <parent>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-parent</artifactId>
4 <version>1.3.5.RELEASE</version>
5 <relativePath/> <!-- lookup parent from repository -->
6 </parent>
7
8 <dependencies>
9 <dependency>
10 <groupId>org.springframework.boot</groupId>
11 <artifactId>spring-boot-starter-test</artifactId>
12 <scope>test</scope>
13 </dependency>
14
15 <dependency>
16 <groupId>org.springframework.cloud</groupId>
17 <artifactId>spring-cloud-starter-eureka-server</artifactId>
18 </dependency>
19 </dependencies>
20
21 <dependencyManagement>
22 <dependencies>
23 <dependency>
24 <groupId>org.springframework.cloud</groupId>
25 <artifactId>spring-cloud-dependencies</artifactId>
26 <version>Brixton.RELEASE</version>
27 <type>pom</type>
28 <scope>import</scope>
29 </dependency>
30 </dependencies>
31 </dependencyManagement>
通过@EnableEurekaServer注解启动一个服务注册中心提供给其他应用进行调用。这一步非常的简单,只需要在一个普通的Spring Boot应用中添加这个注解就能开启此功能,比如下面的例子:
1 package com;
2
3 import org.springframework.boot.autoconfigure.SpringBootApplication;
4 import org.springframework.boot.builder.SpringApplicationBuilder;
5 import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
6
7 @EnableEurekaServer//服务注册中心开启注解
8 @SpringBootApplication
9 public class Application {
10
11 public static void main(String[] args) {
12 new SpringApplicationBuilder(Application.class).web(true).run(args);
13 }
14
15 }
在默认设置下,该服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为,只需要在application.properties中问增加如下配置:
1 #启动端口
2 server.port=1111
3
4 #关闭掉自己往服务中心注册的机制
5 eureka.client.register-with-eureka=false
6 #是否检索服务
7 eureka.client.fetch-registry=false
8 #服务中心地址
9 eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
项目结构:

启动项目访问 http://localhost:1111/
界面如下

三:创建服务提供者
下面我们创建提供服务的客户端,并向服务注册中心注册自己。
假设我们有一个提供计算功能的微服务模块,我们实现一个RESTful API,通过传入两个参数a和b,最后返回a + b的结果。
首先,创建一个基本的Spring Boot应用,在pom.xml中,加入如下配置:
1 <parent>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-parent</artifactId>
4 <version>1.3.5.RELEASE</version>
5 <relativePath/> <!-- lookup parent from repository -->
6 </parent>
7
8 <dependencies>
9 <dependency>
10 <groupId>org.springframework.boot</groupId>
11 <artifactId>spring-boot-starter-test</artifactId>
12 <scope>test</scope>
13 </dependency>
14
15 <dependency>
16 <groupId>org.springframework.cloud</groupId>
17 <artifactId>spring-cloud-starter-eureka</artifactId>
18 </dependency>
19 </dependencies>
20
21 <dependencyManagement>
22 <dependencies>
23 <dependency>
24 <groupId>org.springframework.cloud</groupId>
25 <artifactId>spring-cloud-dependencies</artifactId>
26 <version>Brixton.RELEASE</version>
27 <type>pom</type>
28 <scope>import</scope>
29 </dependency>
30 </dependencies>
31 </dependencyManagement>
创建我们的业务访问控制器
1 package com;
2
3 import org.apache.log4j.Logger;
4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.cloud.client.ServiceInstance;
6 import org.springframework.cloud.client.discovery.DiscoveryClient;
7 import org.springframework.web.bind.annotation.RequestMapping;
8 import org.springframework.web.bind.annotation.RequestMethod;
9 import org.springframework.web.bind.annotation.RequestParam;
10 import org.springframework.web.bind.annotation.RestController;
11
12 @RestController
13 public class ComputeController {
14
15 private final Logger logger = Logger.getLogger(getClass());
16
17 @Autowired
18 private DiscoveryClient client;
19
20 @RequestMapping(value = "/add" ,method = RequestMethod.GET)
21 public Integer add(@RequestParam Integer a, @RequestParam Integer b) {
22 ServiceInstance instance = client.getLocalServiceInstance();
23 Integer r = a + b;
24 logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);
25 return r;
26 }
27
28 }
创建启动器
EnableDiscoveryClient注解,该注解能激活Eureka中的DiscoveryClient实现,才能实现Controller中对服务信息的输出。
package com; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient//标识客户端,并扫描控制器里面的DiscoveryClient
@SpringBootApplication
public class ComputeServiceApplication { public static void main(String[] args) {
new SpringApplicationBuilder(ComputeServiceApplication.class).web(true).run(args);
} }
application.properties
1 #指定微服务的名称后续在调用的时候只需要使用该名称就可以进行服务的访问。
2 spring.application.name=compute-service
3 server.port=2222
4 #属性对应服务注册中心的配置内容,指定服务注册中心的位置。
5 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
启动本项目,然后再访问http://localhost:1111/就可以看到服务已经注册到服务中心
四:创建服务的消费者
使用ribbon实现负载均衡的消费者,构建一个基本Spring Boot项目,并在pom.xml中加入如下内容:
1 <parent>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-parent</artifactId>
4 <version>1.3.5.RELEASE</version>
5 <relativePath/> <!-- lookup parent from repository -->
6 </parent>
7
8 <dependencies>
9 <dependency>
10 <groupId>org.springframework.cloud</groupId>
11 <artifactId>spring-cloud-starter-ribbon</artifactId>
12 </dependency>
13 <dependency>
14 <groupId>org.springframework.cloud</groupId>
15 <artifactId>spring-cloud-starter-eureka</artifactId>
16 </dependency>
17 <dependency>
18 <groupId>org.springframework.boot</groupId>
19 <artifactId>spring-boot-starter-web</artifactId>
20 </dependency>
21 <dependency>
22 <groupId>org.springframework.boot</groupId>
23 <artifactId>spring-boot-starter-test</artifactId>
24 <scope>test</scope>
25 </dependency>
26 </dependencies>
27
28 <dependencyManagement>
29 <dependencies>
30 <dependency>
31 <groupId>org.springframework.cloud</groupId>
32 <artifactId>spring-cloud-dependencies</artifactId>
33 <version>Brixton.RELEASE</version>
34 <type>pom</type>
35 <scope>import</scope>
36 </dependency>
37 </dependencies>
38 </dependencyManagement>
通过@LoadBalanced注解实现负载均衡的开启
1 package com;
2
3 import org.springframework.boot.SpringApplication;
4 import org.springframework.boot.autoconfigure.SpringBootApplication;
5 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
6 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
7 import org.springframework.context.annotation.Bean;
8 import org.springframework.web.client.RestTemplate;
9
10 @SpringBootApplication
11 @EnableDiscoveryClient
12 public class RibbonApplication {
13
14 @Bean
15 @LoadBalanced//负载均衡的开启
16 RestTemplate restTemplate() {
17 return new RestTemplate();
18 }
19
20 public static void main(String[] args) {
21 SpringApplication.run(RibbonApplication.class, args);
22 }
23
24 }
创建ConsumerController来消费COMPUTE-SERVICE的add服务。通过直接RestTemplate来调用服务,计算10 + 20的值。
1 package com;
2
3 import org.springframework.beans.factory.annotation.Autowired;
4 import org.springframework.web.bind.annotation.RequestMapping;
5 import org.springframework.web.bind.annotation.RequestMethod;
6 import org.springframework.web.bind.annotation.RestController;
7 import org.springframework.web.client.RestTemplate;
8
9 @RestController
10 public class ConsumerController {
11
12 @Autowired
13 RestTemplate restTemplate;
14
15 @RequestMapping(value = "/add", method = RequestMethod.GET)
16 public String add() {
17 return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody();
18 }
19 //
20 }
application.properties中配置eureka服务注册中心
1 spring.application.name=ribbon-consumer
2 server.port=3333
3 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
这个时候修改服务提供方把端口改为2223,再启动一个服务提供
可一看到服务中心已经被注册了两个服务。

启动服务消费方,并访问五次:http://localhost:3333/add
然后,打开compute-service的两个服务提供方,分别输出了类似下面的日志内容:
端口2222的 
端口2223的

可以看到,之前启动的两个compute-service服务端分别被调用了三次,两次。到这里,我们已经通过Ribbon在客户端已经实现了对服务调用的均衡负载。
基于SpringCloud的服务注册和调用的更多相关文章
- SpringCloud+Consul 服务注册与服务发现
SpringCloud+Consul 服务注册与服务发现 1. 服务注册: 在Spring.factories有一段: # Discovery Client Configuration org.spr ...
- 【转帖】基于Zookeeper的服务注册与发现
http://www.techweb.com.cn/network/hardware/2015-12-25/2246973.shtml 背景 大多数系统都是从一个单一系统开始起步的,随着公司业务的快速 ...
- .net core + eureka + spring boot 服务注册与调用
.net core + eureka + spring boot 服务注册与简单的调用 假期小长假遇上疫情只能去家里蹲了,刚好有时间总结一下. 概述 微服务架构是当前比较火的分布式架构,本篇基于.ne ...
- Web Api 基于Zookeeper的服务注册与发现
安装与差异 Zookeeper安装请参考我上篇文章 http://www.cnblogs.com/woxpp/p/7700368.html 基于Nginx的服务提供和消费 基于zookeeper的服务 ...
- SpringCloud之服务注册-eureka
类似于DUBBO 的zookeeper, SpringCloud本身提供一套服务注册中心--eureka 与zookeeper的区别在于 1:zookeeper本身就是一个应用,安装即可用:eurek ...
- SpringCloud - 2. 服务注册 和 发现
SpringCloud 的服务注册和发现是由Eureka来完成. 1.eureka server 1.1 依赖 <dependency> <groupId>org.spring ...
- 将SpringCloud Eureka 服务注册与发现部署到docker
一.前言 最近在学习docker,顺便把之前学习的spring cloud 部署到Docker 中.至于什么是SpringCloud的服务注册与发现,什么是docker,我这里就不作赘述了.可以先去学 ...
- springcloud之服务注册与发现(Eureka)
springcloud服务注册与发现 使用Eureka实现服务治理 作用:实现服务治理(服务注册与发现) 简介: Spring Cloud Eureka是Spring Cloud Netflix项目下 ...
- SpringCloud——Eureka服务注册和发现
一.SpringCloud和Dubbo SpringCloud整合了一套较为完整的微服务解决方案框架,而Dubbo只是解决了微服务的几个方面的问题. content Dubbo SpringCloud ...
随机推荐
- SpringBoot集成Redis
1.引入 spring-boot-starter-redis <dependency> <groupId>redis.clients</groupId> <a ...
- Angular学习第一步
前端开发越来越流行了,作为后端开发人员,也开始需要学习前端了.随着前端技术的发展,前端技术也越来越复杂,复杂程度不亚于后端,各种框架各种设计模式前端都用上了,什么AngularJS,Angular, ...
- 使用shell脚本来自动化处理我们的工作,解放双手
Shell脚本介绍 1.Shell脚本,就是利用Shell的命令解释的功能,对一个纯文本的文件进行解析,然后执行这些功能,也可以说Shell脚本就是一系列命令的集合. 2.Shell可以直接使用在wi ...
- springboot aop 自定义注解方式实现完善日志记录(完整源码)
版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 一:功能简介 本文主要记录如何使用aop切面的方式来实现日志记录功能. 主要记录的信息有: 操作人,方法名,参数,运行时间,操作类型 ...
- 基于Visual Studio .NET2015的单元测试
基于Visual Studio .NET2015的单元测试 1. 在Visual Studio .NET2015中创建任意项目. 2. 在某个公共类的公共方法的名称上面点击右键,选择“创建 ...
- c# 获取客户端文件
/// <summary> /// 获取有效客户端文件控件集合,文件控件必须上传了内容,为空将被忽略, /// 注意:Form标记必须加入属性 enctype="multipar ...
- c#实战开发:用.net core开发一个简单的Web以太坊钱包 (六)
今天就来开发一个C# 版的简易钱包 先回顾以前的内容 c#实战开发:以太坊Geth 命令发布智能合约 (五) c#实战开发:以太坊Geth 常用命令 (四) c#实战开发:以太坊钱包快速同步区块和钱包 ...
- 一道生成不重复随机数字的C#笔试编程题
当时写在纸上的程序没有验证输入,出面试公司没多久就突然想起来这点了,囧啊! 不过当时笔试的时候想到写异常处理了. 回来上机整理了一下程序,才发现原来还会用到递归的. 当时面试官边说边出的题,问他数字是 ...
- What are the differences between struct and class in C++?
Question: This question was already asked in the context of C#/.Net. Now I'd like to learn the diffe ...
- 【读书笔记】iOS-iOS安全基础知识
一,iOS硬件/设备的类型. iPad的问世,就是在这一方向上迈出的第一步.第一代iPad使用了ARM Cortex-A8架构的CUP,它的速度大约是第一代iPhone所使用CPU速度的两倍. iPa ...