Spring Cloud 为开发者提供了在分布式系统中的一些常用的组件(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁定,决策竞选,分布式会话集群状态)。使用Spring Cloud开发人员可以快速地完成实现这些模式的服务和应用程序。它们在任何分布式环境中都能很好地工作

Ribbon

Ribbon 是 Netflix 开源的基于 HTTP 和 TCP 的客户端负载均衡器框架,目前也已被 Spring Cloud 团队集成在 spring-cloud-netflix子项目下,主要用于客户端软负载功能,内部已实现了 随机轮训权重减压(选取压力最小的) 等常见的负载算法,同时也提供了 ILoadBalance 与 IRule 两个接口方便我们自己编写适合自己的负载算法

  • 负载均衡
  • 容错
  • 多协议(HTTP,TCP,UDP)支持异步和反应模型
  • 缓存和批处理

交互图

交互图

Try

要尝试 Spring Cloud Ribbon 首要的就是准备一个服务注册中心,还不太清楚的可以在回头看看上一章 认识Eureka ,这里就不做过多赘述了,准备 eureka-server(回顾上一章)product-serverorder-server 三个项目,后面的两个可以理解为上一章的 eureka-client

Eureka Server

详情参考上一章,或从文末的 GITHUB 链接获取对应篇幅的完整代码

Product Server

一个普通的 Eureka Client 即可,详情参考上一章,或从文末的 GITHUB 链接获取对应篇幅的完整代码

Order Server

一个普通的 Eureka Client

依赖

细心的小伙伴会发现,这和一个普通的 Eureka Client 也没啥区别啊,没任何额外依赖的,那是因为在 spring-cloud-starter-netflix-eureka-client 中已经帮我们依赖过 spring-cloud-starter-netflix-ribbon 了。假如使用 consulzookeeperetcd 等容器为服务发现为者时,就必须依赖 spring-cloud-starter-netflix-ribbon 包

1
2
3
4
5
6
7
8
9
10
<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>

配置文件

在 src/main/resources 目录下创建一个 bootstrap.yml 的文件,写上 eureka 相关配置信息

1
2
3
4
5
6
7
8
9
10
11
12
server:
port: 7072
spring:
application:
name: order-server
eureka:
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}
client:
service-url:
defaultZone: http://localhost:7071/eureka/

主函数

各位小伙伴对 Spring Boot 中的 RestTemplate 应该都不陌生,它是由 Spring Boot 提供而不是 Spring Cloud ,无负载功能,为了方便开发者,Spring Cloud 团队提供了一个 @LoadBalanced 注解(默认采用轮训算法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.battcn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate; /**
* @author Levin
*/
@EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication { @Configuration
class MyConfiguration {
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
} public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}

控制器

客户端(order-server:7702)从 Eureka Server 同步了 product-server:7703 和 product-server:7704 这个时候它是如何知晓注册表中的信息呢?上一章中遗留了一个知识点就是 DiscoveryClient ,通过它就可以获得注册表中客户端的信息了,下列代码块演示了 DiscoveryClient 的简单用法,更多 API 可以自行尝试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.battcn.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; import java.util.List; /**
* @author Levin
* @since 2018/9/28 0028
*/
@RestController
@RequestMapping("/orders")
public class OrderController { private final RestTemplate restTemplate;
private final DiscoveryClient discoveryClient; @Autowired
public OrderController(RestTemplate restTemplate, DiscoveryClient discoveryClient) {
this.restTemplate = restTemplate;
this.discoveryClient = discoveryClient;
} @GetMapping
public String query() {
final List<String> services = discoveryClient.getServices();
for (String service : services) {
List<ServiceInstance> list = discoveryClient.getInstances(service);
for (ServiceInstance instance : list) {
System.out.println(instance.getUri() + "/" + service + " - " + instance.getServiceId());
}
}
return restTemplate.getForObject("http://PRODUCT-SERVER/products", String.class);
}
}

Why

有的小伙伴对上面的内容会存在一些疑问,为什么没有写 IP:PORT 了,而是写了一串字符,它是怎么做到的?

1
2
3
4
5
6
7
8
9
10
11
12
13
用通俗的概念来说,它就是编码与解码操作,还记得 Eureka Server UI 中 Application 吗? 
编码:根据 spring.application.name 设置 serviceId
Server ID:PRODUCT-SERVER
Client A :http://localhost:7073/products
Client B :http://localhost:7074/products 解码:通过 serviceId 找到对应的客户端,
然后根据客户端配置的负载算法从对应集合中
找出符合当前算法条件的结果,最后拼接出相应的 http 地址即可 解码前:http://PRODUCT-SERVER/products
那么将 http://PRODUCT-SERVER 替换成 instance.getUri() 内容是不是就出来了
http://localhost:7073/products 和 http://localhost:7074/products

效果图

自定义 IRule

假如我们不想使用轮训了,换换口味改成随机算法,又或者想自己写一套适合自己的负载算法,可以用下面这种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.battcn.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* @author Levin
* @since 2018/9/28 0028
*/
@Configuration
public class RibbonRuleConfiguration { @Bean
public IRule ribbonRule() {
return new RandomRule();
}
} @RibbonClient(name = "ribbonRule",configuration = RibbonRuleConfiguration.class)
public class OrderController { }

Ribbon软负载 (F版)的更多相关文章

  1. spring cloud 系列第3篇 —— ribbon 客户端负载均衡 (F版本)

    源码仓库地址:https://github.com/heibaiying/spring-samples-for-all 一.ribbon 简介 ribbon是Netfix公司开源的负载均衡组件,采用服 ...

  2. SpringCloud Netflix Ribbon(负载均衡)

    ⒈Ribbon是什么? Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具. Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负 ...

  3. 使用ZooKeeper实现软负载均衡(原理)

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,提供的功能包括配置维护.名字服务.分布式同步.组服务等. ZooKeeper会维护一个树形的数据结构,类似于Windows资源管理器 ...

  4. vmware linux top si高以及网卡队列、软负载相关优化

    今日,测试公司自行开发的一rpc中间件,期间发现top si的比例很高,且几乎只有一个cpu是繁忙的,其他均基本为0. 经查,si主要是系统软中断,最后确定是网卡导致的系统中断.于是,往上搜了下资料, ...

  5. 基于Ubuntu12.04-server版的openstack F版搭建步骤

    本文为双节点搭建,分为计算(IP1)和控制节点(IP2) 说明: 计算节点组件: 1.mysql 2.keystone 3.Nova 4.glance 5.rabbitmq 控制节点组件: 1.cin ...

  6. Spring Cloud Ribbon——客户端负载均衡

    一.负载均衡负载均衡(Load Balance): 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽.增加吞吐量.加强网络数据处理能力.提高网络的灵活性和可用性.其意思 ...

  7. 趣味编程:CPS风格代码(C#,F#版)

    CPS风格代码(C#版) using System; namespace fp { class CPS { static int add(int x, int y) => x + y; stat ...

  8. 软工 · BETA 版冲刺前准备(团队)

    软工 · BETA 版冲刺前准备(团队) 过去存在的问题 组员之间缺乏沟通,前后端缺乏沟通协作 组员积极性不高 基础知识不够扎实 手动整合代码效率过低 我们已经做了哪些调整/改进 通过会议加强组员之间 ...

  9. Spring Cloud:使用Ribbon实现负载均衡详解(下)

    在上一篇文章(Spring Cloud:使用Ribbon实现负载均衡详解(上))中,我对 Ribbon 做了一个介绍,Ribbon 可以实现直接通过服务名称对服务进行访问.这一篇文章我详细分析一下如何 ...

随机推荐

  1. Java实现 LeetCode 729 我的日程安排表 I(二叉树)

    729. 我的日程安排表 I 实现一个 MyCalendar 类来存放你的日程安排.如果要添加的时间内没有其他安排,则可以存储这个新的日程安排. MyCalendar 有一个 book(int sta ...

  2. Java实现 LeetCode 347 前 K 个高频元素

    347. 前 K 个高频元素 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输 ...

  3. Java实现蓝桥杯3n+1问题

    3n+1 [问题描述] 考虑如下的序列生成算法:从整数 n 开始,如果 n 是偶数,把它除以 2:如果 n 是奇数,把它乘 3 加1.用新得到的值重复上述步骤,直到 n = 1 时停止.例如,n = ...

  4. Java实现 LeetCode 115 不同的子序列

    115. 不同的子序列 给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数. 一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字 ...

  5. Java实现猜底牌问题(贪婪法)

    1 问题描述 设计一种策略,使在下面的游戏中,期望提问的次数达到最小.有一副纸牌,是由1张A,2张2,3张3,-9张9组成的,一共包含45张牌.有人从这副牌洗过的牌中抽出一张牌,问一连串可以回答是或否 ...

  6. CSS 简介/特点/优势/给特定浏览器提供不同样

    1.CSS简介 CSS全称Cascading Style Sheet,可译为“层叠样式表”或“级联样式表”,通常称为CSS样式或者样式表.CSS是一些纯文本内容,文件格式为.css. 2.CSS特点 ...

  7. 欧几里得算法求最大公约数-《Algorithms Fourth Edition》第1章

    最大公约数(Greatest Common Divisor, GCD),是指2个或N个整数共有约数中最大的一个.a,b的最大公约数记为(a, b).相对应的是最小公倍数,记为[a, b]. 在求最大公 ...

  8. Centos6.5--svn搭建

    0x01 配置好镜像源安装svn yum install subversion -y 0x02 安装完成之后在/opt下面新建一个svn的目录,当然也可以在其他的地方建立svn目录,这个看个人爱好. ...

  9. iOS-Code Data多线程的封装详解

    Code Data 的单例封装:      很容易发现,系统生成的模版代码将Core Data 的基本的准备(貌似还挺复杂!)都放在 AppDelegate中了,可苹果公司为什么会这么做呢?     ...

  10. 2019-02-08 Python学习之Scrapy的简单了解

    今天遇到的问题和昨天差不多,一个Scrapy装了好久,anaconda卸了又装,pycharm卸了又装,环境变量配置一堆,依赖包下载一堆.查了一堆资料总算是搞好了. Scripy: 先放个框架结构图( ...