参考资料:
《Spring Microservices in Action》
《Spring Cloud Alibaba 微服务原理与实战》
《B站 尚硅谷 SpringCloud 框架开发教程 周阳》
Spring Cloud Ribbon 是基于 Netflix Ribbon 实现的一套客户端负载均衡的工具;提供客户端的软件负载均衡算法和服务调用;


<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
在服务消费者的 client 包下;
@Component
public class ProviderDiscoveryClient {
//自动注入 DiscoveryClient 类,该类用于与 Ribbon 交互
@Autowired
private DiscoveryClient discoveryClient;
public Provide getProvide(String providerId) {
RestTemplate restTemplate = new RestTemplate();
//获取服务提供者的所有实例列表,ServiceInstance 用于保存关于服务的特定实例(包括主机名、端口荷 URL)
List<ServiceInstance> instances = discoveryClient.getInstances("provider-instance-name");
if (instances.size()==0) return null;
//检索要调用的服务端点
String serviceUri = String.format("%s/providers/%s",instances.get(0).getUri().toString(), providerId);
//使用标准的 Spring REST 模板类去调用服务
ResponseEntity< provider > restExchange =
restTemplate.exchange(
serviceUri,
HttpMethod.GET,
null, Provider.class, providerId);
return restExchange.getBody();
}
}
这种方法存在以下问题:
结合本篇《5. 本地负载均衡器的实现(消费者)》即可用到客户端负载均衡,即:开发人员定义了本地负载均衡器来实现了负载均衡;
@SpringBootApplication //只需要这个注解即可
public class Application {
@LoadBalanced //告诉 Spring Cloud 创建一个支持 Ribbon 的 RestTemplate
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@LoadBalanced 注解显式标注,才能将 Ribbon 和 RestTemplate 一起使用;@Configuration
public class ApplicationContextConfig{
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
在服务消费者的 client 包下;
@Component
public class ProviderRestTemplateClient {
//自动注入即可,不用实例化
@Autowired
RestTemplate restTemplate;
public Provider getProvider(String providerId){
ResponseEntity<Provider> restExchange =
restTemplate.exchange(
//使用 Eureka 服务 ID 来构建目标 URL
"http://provider-instance-name/providers/{providerId}",
HttpMethod.GET,
null, Provider.class, providerId);
return restExchange.getBody();
}
}
Feign 相关知识将在下篇《4.2 基于 Feign 与 OpenFeign 的服务接口调用》中说明,这里仅把重点放在与上述两种调用提供者服务的区别与对比;
@EnableFeignClients:表示启用 Feign 客户端;
@FeignClient("provider-instance-name") //标识服务为 feign 的客户端
public interface ProviderFeignClient {
//定义端点的路径和动作
@RequestMapping(
method= RequestMethod.GET,
value="/providers/{providerId}",
consumes="application/json")
//定义传入端点的参数,该方法可以由客户端调用以触发组织服务
Provider getProvider(@PathVariable("providerId") String providerId);
}
指切换默认的负载均衡算法,切换后的仍为现成的(与本地负载均衡器有所区别,本地负载均衡器要自己实现);
@ComponentScan 所扫描的当前包下以及子包下,否则自定义的配置类会被所有的Ribbon客户端所共享,达不到自定义的目的;@ComponentScan 注解被封装到主启动类上的 @SpringBootApplication 注解。其默认扫描主启动类所在包及其子包,因此我们要返回上一级目录新建一个 myRule 目录存放我们自定义的负载均衡配置类;
@Configuration
public class MySelfRule {
@Bean
public IRule myRule(){
return new RandomRule();//定义为随机
}
}
name:指定服务提供者的实例名称;configuration:指定需要使用哪个配置类的负载均衡;指切换默认的负载均衡算法,切换后的仍为现成的(与本地负载均衡器有所区别,本地负载均衡器要自己实现);
#服务提供者的实例名称
provider-instance-name:
ribbon:
#代表 Ribbon 使用的负载均衡策略,属性的值为:IRule 的实现类
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
#其他可用的配置属性
# NFLoadBalancerClassName : 配置 ILoadBalancer 的实现类
# NFLoadBalancerPingClassName : 配置 IPing 的实现类
# NIWSServerListClassName: 配置 ServerList 的实现类
# NIWSServerListFilterClassName: 配置 ServerListtFilter 的实现类
本地负载均衡器不同于自定义负载均衡算法;前者的负载均衡算法需要自己手动实现,后者只是切换成另一种现成的负载均衡算法;
可以新建一个包,专门存放我们自己写的负载均衡算法;
public interface LoadBalancer{
ServiceInstance instances(List<ServiceInstance> serviceInstances);
}
@Component
public class MyLB implements LoadBalancer{
private AtomicInteger atomicInteger = new AtomicInteger(0);
public final int getAndIncrement(){
int current;
int next;
do {
current = this.atomicInteger.get();
next = current >= 2147483647 ? 0 : current + 1;
}while(!this.atomicInteger.compareAndSet(current,next));
System.out.println("*****第几次访问,次数next: "+next);
return next;
}
//负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标 ,每次服务重启动后rest接口计数从1开始。
@Override
public ServiceInstance instances(List<ServiceInstance> serviceInstances){
int index = getAndIncrement() % serviceInstances.size();
return serviceInstances.get(index);
}
}
@RestController
public class OrderController{
//服务提供者示例的名字
public static final String PAYMENT_URL = "http://provider-instance-name";
@Resource
private RestTemplate restTemplate;
@Resource
private LoadBalancer loadBalancer;
@Resource
private DiscoveryClient discoveryClient;
@GetMapping(value = "/provider/mylb")
public String getProviderLB(){
//获取服务提供者的所有实例列表
List<ServiceInstance> instances = discoveryClient.getInstances("provider-instance-name");
if(instances == null || instances.size() <= 0){
return null;
}
//使用本地负载均衡器选出提供者服务
ServiceInstance serviceInstance = loadBalancer.instances(instances);
URI uri = serviceInstance.getUri();
return restTemplate.getForObject(uri+"/provider/mylb",String.class);
}
}

为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"
我是一名决定学习Ruby和RubyonRails的ASP.NETMVC开发人员。我已经有所了解并在RoR上创建了一个网站。在ASP.NETMVC上开发,我一直使用三层架构:数据层、业务层和UI(或表示)层。尝试在RubyonRails应用程序中使用这种方法,我发现没有关于它的信息(或者也许我只是找不到它?)。也许有人可以建议我如何在RubyonRails上创建或使用三层架构?附言我使用ruby1.9.3和RubyonRails3.2.3。 最佳答案 我建议在制作RoR应用程序时遵循RubyonRails(RoR)风格。Rails
我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源
我正在尝试消除使用Bootstrap3的Rails4元素中的glyphicon错误。我没有使用任何Bootstrapgem将其添加到Assets管道中。我手动将bootstrap.css和bootstrap.js添加到各自的app/assets目录下,分别添加到application.css和application.js什么的我现在在网络浏览器的控制台中看到以下内容:GEThttp://localhost:3000/fonts/glyphicons-halflings-regular.woff404(NotFound)localhost/:1GEThttp://localhost:30
我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n