Spring Cloud(二)《服务提供与负载均衡调用 Eureka》

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: 本章节提供一个基于Eurka的服务注册中心,两个服务提供者之后分别使用Ribbon、Fegin方式进行调用,测试负载均衡。

前言介绍

本章节提供一个基于Eurka的服务注册中心,两个服务提供者之后分别使用Ribbon、Fegin方式进行调用,测试负载均衡。

16.jpg服务提供者Service Provider 本质上是一个 Eureka Client,它在服务启动时,会调用服务注册方法,向 Eureka Server注册接口服务信息,包括地址、端口、服务名、入参、返回值等。当Eureka Server收到注册信息后,会维护在自己的注册列表,如下;

1private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry
2        = new ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>();

服务消费者Service Consumer 本质也是一个 Eureka Client,它在服务启动时,也会向 Eureka Server 注册服务信息。同时在启动后会从Eureka Server 上获取所有实例的注册信息,包括 IP 地址、端口等,并缓存到本地。这个获取有一定的延时,因此我们在实际开发过程中如果服务方尚未启动完成,调用方不要着急启动避免造成调用失败。

案例说明

本案例在itstack-demo-springcloud-02工程中提供单个服务注册、服务提供方、Ribbon调用、Fegin调用,通过修改端口启动2个提供方来模拟测试负载均衡。

环境准备

1、jdk 1.8

2、Spring Boot 2.0.6.RELEASE

3、Spring Cloud Finchley.SR2

代码示例

1itstack-demo-springcloud-02
 2├── itstack-demo-springcloud-eureka-client
 3│   └── src
 4│       └── main
 5│           ├── java
 6│           │   └── org.itstack.demo
 7│           │        ├── web
 8│           │        │   └── EurekaClientController.java
 9│           │        └── EurekaClientApplication.java
10│           └── resources   
11│               └── application.yml
12├── itstack-demo-springcloud-eureka-server
13│   └── src
14│       └── main
15│           ├── java
16│           │   └── org.itstack.demo
17│           │        └── EurekaServerApplication.java
18│           └── resources   
19│               └── application.yml
20├── itstack-demo-springcloud-feign
21│   └── src
22│       └── main
23│           ├── java
24│           │   └── org.itstack.demo
25│           │        ├── service
26│           │        │   └── FeignService.java
27│           │        ├── web
28│           │        │   └── FeignController.java
29│           │        └── FeignApplication.java
30│           └── resources   
31│               └── application.yml
32└── itstack-demo-springcloud-ribbon
33    └── src
34        └── main
35            ├── java
36            │   └── org.itstack.demo
37            │        ├── service
38            │        │   └── RibbonService.java
39            │        ├── web
40            │        │   └── RibbonController.java        
41            │        └── RibbonApplication.java
42            └── resources   
43                └── application.yml

完整代码欢迎关注公众号:bugstack虫洞栈 | 回复“SpringCloud专题”进行下载

itstack-demo-springcloud-eureka-client | 服务提供方

提供一个查询用户信息的简单方法,在配置文件中通过修改端口启动2次,模拟双实例应用,为调用方负载做准备。

web/EurekaClientController.java | 注意@EnableEurekaClient用于向注册中心提供服务

1/**
 2 * 微信公众号:bugstack虫洞栈 | 沉淀、分享、成长,专注于原创专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6@EnableEurekaClient
 7@RestController
 8public class EurekaClientController {
 9
10    @Value("${server.port}")
11    private int port;
12
13    @RequestMapping(path = "/api/queryUserInfo", method = RequestMethod.GET)
14    public String queryUserInfo(@RequestParam String userId) {
15        return "Hi 微信公众号:bugstack虫洞栈 | " + userId + " >: from eureka client port: " + port;
16    }
17
18}

EurekaClientApplication.java | 服务启动类

1/**
 2 * 微信公众号:bugstack虫洞栈 | 沉淀、分享、成长,专注于原创专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6@SpringBootApplication
 7public class EurekaClientApplication {
 8
 9    public static void main(String[] args) {
10        SpringApplication.run(EurekaClientApplication.class, args);
11    }
12
13}

application.yml | 配置文件链接服务注册中心,8001\8002分别配置启动

1server:
 2  port: 8001 / 8002
 3
 4spring:
 5  application:
 6    name: itstack-demo-springcloud-eureka-client
 7
 8eureka:
 9  client:
10    serviceUrl:
11      defaultZone: http://localhost:7397/eureka/

itstack-demo-springcloud-eureka-server | 单个服务注册中心

服务注册中心用于承载接口提供方向上注册,同时正在调用方链接后可以获取指定应用的服务实例。

EurekaServerApplication.java | 通过注解@EnableEurekaServer启动服务注册与发现中心

1/**
 2 * 微信公众号:bugstack虫洞栈 | 沉淀、分享、成长,专注于原创专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6@SpringBootApplication
 7@EnableEurekaServer
 8public class EurekaServerApplication {
 9
10    public static void main(String[] args) {
11        SpringApplication.run( EurekaServerApplication.class, args );
12    }
13
14}

application.yml | 服务注册中心配置文件,端口7397和我们之前写netty的服务的端口一致

1server:
 2  port: 7397
 3
 4eureka:
 5  instance:
 6    hostname: localhost
 7  client:
 8    registerWithEureka: false
 9    fetchRegistry: false
10    serviceUrl:
11      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
12
13spring:
14  application:
15    name: itstack-demo-springcloud-eureka-server

itstack-demo-springcloud-feign | Feign服务调用方

Feign 是一个声明式的 Web Service 客户端,它的目的就是让 Web Service 调用更加简单。它整合了 Ribbon 和 Hystrix,从而让我们不再需要显式地使用这两个组件。Feign 还提供了 HTTP 请求的模板,通过编写简单的接口和插入注解,我们就可以定义好 HTTP 请求的参数、格式、地址等信息。接下来,Feign 会完全代理 HTTP 的请求,我们只需要像调用方法一样调用它就可以完成服务请求。

Feign 具有如下特性:

可插拔的注解支持,包括 Feign 注解和 JAX-RS 注解

支持可插拔的 HTTP 编码器和解码器

支持 Hystrix 和它的 Fallback

支持 Ribbon 的负载均衡

支持 HTTP 请求和响应的压缩

service/FeignService.java | 注解方式调用,方便易用。@FeignClient会在调用时进行解析服务到具体的http://ip:port/

1/**
 2 * 微信公众号:bugstack虫洞栈 | 沉淀、分享、成长,专注于原创专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6@FeignClient(value = "itstack-demo-springcloud-eureka-client")
 7public interface FeignService {
 8
 9    @RequestMapping(value = "/api/queryUserInfo", method = RequestMethod.GET)
10    String queryUserInfo(@RequestParam String userId);
11
12}

web/FeignController.java | 使用接口提供服务 From Feign

1/**
 2 * 微信公众号:bugstack虫洞栈 | 沉淀、分享、成长,专注于原创专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6@RestController
 7public class FeignController {
 8
 9    @Resource
10    private FeignService ribbonService;
11
12    @RequestMapping(path = "/api/queryUserInfo", method = RequestMethod.GET)
13    public String queryUserInfo(@RequestParam String userId) {
14        return ribbonService.queryUserInfo(userId) + " From Feign";
15    }
16
17}

FeignApplication.java | 注解@EnableEurekaClient、@EnableFeignClients、@EnableDiscoveryClient获取调用注册中心服务

1/**
 2 * 微信公众号:bugstack虫洞栈 | 沉淀、分享、成长,专注于原创专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6@SpringBootApplication
 7@EnableEurekaClient
 8@EnableDiscoveryClient
 9@EnableFeignClients
10public class FeignApplication {
11
12    public static void main(String[] args) {
13        SpringApplication.run(FeignApplication.class, args);
14    }
15
16}

application.yml | eureka服务配置,从注册中心获取可用服务

1server:
 2  port: 9001
 3
 4spring:
 5  application:
 6    name: itstack-demo-springcloud-feign
 7
 8eureka:
 9  client:
10    serviceUrl:
11      defaultZone: http://localhost:7397/eureka/

itstack-demo-springcloud-ribbon | Ribbon服务调用方

Ribbon是一个基于 HTTP 和 TCP 的客户端负载均衡器。它可以通过在客户端中配置 ribbonServerList 来设置服务端列表去轮询访问以达到均衡负载的作用。

当 Ribbon 与 Eureka 联合使用时,ribbonServerList 会被 DiscoveryEnabledNIWSServerList 重写,扩展成从 Eureka 注册中心中获取服务实例列表。同时它也会用 NIWSDiscoveryPing 来取代 IPing,它将职责委托给 Eureka 来确定服务端是否已经启动。

service/RibbonService.java | 接口式硬编码调用不太易于维护,因此也是比较少用的方式

1/**
 2 * 微信公众号:bugstack虫洞栈 | 沉淀、分享、成长,专注于原创专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6@Service
 7public class RibbonService {
 8
 9    @Autowired
10    private RestTemplate restTemplate;
11
12    public String queryUserInfo(String userId) {
13        return restTemplate.getForObject("http://ITSTACK-DEMO-SPRINGCLOUD-EUREKA-CLIENT/api/queryUserInfo?userId=" + userId, String.class);
14    }
15
16}

web/RibbonController.java | 使用接口提供服务 From Ribbon

1/**
 2 * 微信公众号:bugstack虫洞栈 | 沉淀、分享、成长,专注于原创专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6@RestController
 7public class RibbonController {
 8
 9    @Resource
10    private RibbonService ribbonService;
11
12    @RequestMapping(path = "/api/queryUserInfo", method = RequestMethod.GET)
13    public String queryUserInfo(@RequestParam String userId) {
14        return ribbonService.queryUserInfo(userId) + " From Ribbon";
15    }
16
17}

RibbonApplication.java | 通过注解@LoadBalanced注册rest模版,用于Ribbon接口调用

1/**
 2 * 微信公众号:bugstack虫洞栈 | 沉淀、分享、成长,专注于原创专题案例
 3 * 论坛:http://bugstack.cn
 4 * Create by 付政委 on @2019
 5 */
 6@SpringBootApplication
 7@EnableEurekaClient
 8@EnableDiscoveryClient
 9public class RibbonApplication {
10
11    public static void main(String[] args) {
12        SpringApplication.run(RibbonApplication.class, args);
13    }
14
15    @Bean
16    @LoadBalanced
17    RestTemplate restTemplate() {
18        return new RestTemplate();
19    }
20
21}

application.yml | eureka服务配置,从注册中心获取可用服务

1server:
 2  port: 9002
 3
 4spring:
 5  application:
 6    name: itstack-demo-springcloud-ribbon
 7
 8eureka:
 9  client:
10    serviceUrl:
11      defaultZone: http://localhost:7397/eureka/

测试验证

1、启动服务注册中心itstack-demo-springcloud-eureka-server

2、分别启动itstack-demo-springcloud-eureka-client,修改端口8001、8002启动两次提供两个服务

3、启动itstack-demo-springcloud-feign

4、启动itstack-demo-springcloud-ribbon

5、访问服务注册中心http://localhost:7397/

17.jpg

6、访问服务提供方;http://localhost:8001/api/queryUserInfo?userId=111 | 说明服务正常

1Hi 微信公众号:bugstack虫洞栈 | 111 >: from eureka client port: 8001

7、访问Feign服务调用放,每次刷新会看到负载均衡调用到不同端口服务:http://localhost:9001/api/queryUserInfo?userId=111

1Hi 微信公众号:bugstack虫洞栈 | 111 >: from eureka client port: 8002 From Feign
2
3Hi 微信公众号:bugstack虫洞栈 | 111 >: from eureka client port: 8001 From Feign

8、访问Ribbon服务调用放,每次刷新会看到负载均衡调用到不同端口服务:http://localhost:9002/api/queryUserInfo?userId=111

1Hi 微信公众号:bugstack虫洞栈 | 111 >: from eureka client port: 8001 From Ribbon
2
3Hi 微信公众号:bugstack虫洞栈 | 111 >: from eureka client port: 8002 From Ribbon

综上总结

1、在使用SpringCloud时我们可以很轻松的使用到注册中心与很简单的方式去做服务调用

2、以上负载均衡,都是以轮询访问的方式实现的,实际开发过程中还会有一些依赖于机器性能、GC、调用量、响应时间等计算的权重值来做负载IRule

3、服务注册中心,负责维护注册的服务列表,同其他服务注册中心一样,支持高可用配置

4、服务提供方,作为一个 Eureka Client,向 Eureka Server 做服务注册、续约和下线等操作,注册的主要数据包括服务名、机器IP、port、域名等

5、服务消费方,作为一个 Eureka Client,向 Eureka Server 获取 Service Provider 的注册信息,并通过远程调用/负载均衡与 Service Provider 进行通信

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
1月前
|
弹性计算 监控 负载均衡
|
3月前
|
负载均衡 算法 Java
Spring Cloud全解析:负载均衡算法
本文介绍了负载均衡的两种方式:集中式负载均衡和进程内负载均衡,以及常见的负载均衡算法,包括轮询、随机、源地址哈希、加权轮询、加权随机和最小连接数等方法,帮助读者更好地理解和应用负载均衡技术。
102 2
|
1月前
|
运维 负载均衡 算法
|
4月前
|
开发框架 负载均衡 Java
当热门技术负载均衡遇上 Spring Boot,开发者的梦想与挑战在此碰撞,你准备好了吗?
【8月更文挑战第29天】在互联网应用开发中,负载均衡至关重要,可避免单服务器过载导致性能下降或崩溃。Spring Boot 作为流行框架,提供了强大的负载均衡支持,通过合理分配请求至多台服务器,提升系统可用性与可靠性,优化资源利用。本文通过示例展示了如何在 Spring Boot 中配置负载均衡,包括添加依赖、创建负载均衡的 `RestTemplate` 实例及服务接口调用等步骤,帮助开发者构建高效、稳定的应用。随着业务扩展,掌握负载均衡技术将愈发关键。
121 6
|
4月前
|
缓存 NoSQL Java
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
|
25天前
|
消息中间件 监控 Java
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
31 6
|
25天前
|
Java 关系型数据库 MySQL
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
45 5
|
25天前
|
缓存 监控 Java
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
35 5
|
1月前
|
负载均衡 算法 Java
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
89 5
|
22天前
|
负载均衡 Java Nacos
常见的Ribbon/Spring LoadBalancer的负载均衡策略
自SpringCloud 2020版起,Ribbon被弃用,转而使用Spring Cloud LoadBalancer。Ribbon支持轮询、随机、加权响应时间和重试等负载均衡策略;而Spring Cloud LoadBalancer则提供轮询、随机及Nacos负载均衡策略,基于Reactor实现,更高效灵活。
54 0