首页 文章 精选 留言 我的

精选列表

搜索[Excel导题],共7174篇文章
优秀的个人博客,低调大师

万字详解Ribbon架构,针对面试高频题多角度细说Ribbon

为什么要使用Ribbon 上一章节我们学习了注册中心《阿里面试官问我:到底知不知道什么是Eureka,这次,我没沉默》,我们知道但我们存在多个服务提供者的时候,我们会让所有的服务提供者将服务节点信息都注册到EurekaServer中,然后让客户端去拉取一份服务注册列表到本地,服务消费者会从服务注册列表中找到合适的服务实例信息,通过IP:Port的方式去调用服务。 那么,消费者是如何决定调用哪一个服务实例呢,此时,本章节的主人公Ribbon默默的站了起来,笑着说,没错,正是在下。 Srping Cloud Ribbon 是基于 Netflix Ribbon实现的一套 客户端负载均衡的工具。 简单的说,Ribbon是Netflix发布的开源顶目,主要功能是解析配置中或注册中心的服务列表,通过客户端的软件负均衡算法来实现服务请求的分发。 Ribbon客户端组件提供一系列完善配置项如连接超时,重试等。 简单的说,就是在配置文件中列出LoadBalancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(筒单轮洵,随机连接等)去连接这些机器。 我们也很容易使Ribbon实现自定义负载均衡算法。 Ribbon和Nginx又有什么不同呢? 集中式负载均衡 如图所示就是集中式负载均衡集中式负载均衡就好比房屋中介,他手里有很多房屋信息。 服务消费者就好比是需要租房的租客,我们并不能直接的和房屋主人进行租房交易,而是通过房屋中介选择房屋信息达成租房交易。 也就是说,客户端的请求信息并不会直接去请求服务实例,而是在到达负载均衡器的时候,通过负载均衡算法选择某一个服务实例,然后将请求转发到这个服务实例上。 集中式负载均衡又分为硬件负载均衡,如F5,软件负载均衡,如Nginx。 客户端负载均衡 如图所示就是客户端负载均衡就好比,现在有很多租房app,很多房屋的主人并不想通过中介租房,想省一笔中介费。 很多租客也想省一笔中介费,不想通过中介租房,于是租客将App上的租房信息记录在自己的笔记本上。 但是由于租客租房经验不足,并不知道应该选择哪一套房,此时刚好租客有一个做房屋中介好友(就是这么巧),于是租客将好友请到家里来,让他帮忙出谋划策,选择好房源,然后租客到时候直接去看房租房。 也就是说,此时客户端请求不会再去负载均衡器上进行转发了,客户端自己维护了一套服务列表,要掉用的某个服务实例之前首先会通过负载均衡算法选择一个服务节点,直接将请求发送到该服务节点上。 Ribbon 总体架构 首先我们看一张图: 接下来我们详细介绍下上图所示的Ribbon核心的6个组件接口。 IRule 释义:IRule就是根据特定算法中从服务器列表中选取一个要访问的服务,Ribbon默认的算法为轮询算法。 接下来我们来看一张IRule的类继承关系图: 其中用红色方框圈出来的叶子节点是现在还在使用的负载均衡算法,而用紫色方框圈出来的是已经废弃了的。 由图可知,目前我们使用的负载均衡算法有以下几种: RoundRobinRule和WeightedResponseTimeRule 首先说明下 RoundRobinRule(轮询)策略,虽然我没有圈出来但是他是很常用的负载均衡算法,表示表示每次都取下一个服务器。 线性轮询算法实现:每一次把来自用户的请求轮流分配给服务器,从1开始,直到N(服务器个数),然后重新开始循环。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。 通过图上的继承关系我们可知RoundRobinRule和WeightedResponseTimeRule是继承和被继承的关系。 WeightedResponseTimeRule是根据平均响应时间计算所有服务的权重,响应时间越快的服务权重越大被选中的概率越大。 有一个默认每30秒更新一次权重列表的定时任务,该定时任务会根据实例的响应时间来更新权重列表。 但是由于刚启动时如果统计信息不足,则使用RoundRobinRule(轮询)策略,等统计信息足够,会切换到WeightedResponseTimeRule。 AvailabilityFilteringRule AvailabilityFilteringRule会先过滤掉由于多次访问故障而处于断路器状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问。 ZoneAvoidanceRule 综合判断Server所在区域的性能和Server的可用性选择服务器。 BestAvailableRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务。 RandomRule 随机选取服务。 使用 ThreadLocalRandom.current().nextInt(serverCount);随机选择。 RetryRule 先按照RoundRobinRule(轮询)的策略获取服务,如果获取的服务失败侧在指定的时间会进行重试,继续获取可用的服务。 自定义负载均衡算法 自定义负载均衡算法主要分三步: 实现IRule接口或者继承AbstractLoadBalancerRule类 重写choose方法 指定自定义的负载均衡策略算法类 首先我们创建一个MyRule类,但是这个类不能随便乱放。 官方文档给出警告:这个自定义的类不能放在@ComponentScan所扫描的当前包以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是我们达不到特殊化指定的目的了。 MyRule package javaer.study.RibbonTest;​import com.netflix.loadbalancer.IRule;/** * 自定义负载均衡策略 * * @author javaMaster * 公众号:【Java 学习部落】 * @create 2020 09 14 * @Version 1.0.0 */public class MyRule { public IRule myRule () { return new MyRule_CustomAlgorithm (); }} 接下自定义一个负载均衡策略算法MyRule_CustomAlgorithm。 定义算法:每台服务节点调用三次,代码如下 package javaer.study.RibbonTest;​import com.netflix.client.config.IClientConfig;import com.netflix.loadbalancer.AbstractLoadBalancerRule;import com.netflix.loadbalancer.ILoadBalancer;import com.netflix.loadbalancer.Server;​import java.util.List;​/** * 自定义负载均衡算法 * * @author javaMaster * 公众号:【Java学习部落】 * @create 2020 09 14 * @Version 1.0.0 */public class MyRule_CustomAlgorithm extends AbstractLoadBalancerRule { // total = 0 // 当total==5以后,我们指针才能往下走, // index = 0 // 当前对外提供服务的服务器地址, // total需要重新置为零,但是已经达到过一个5次,我们的index = 1 // 分析:我们5次,但是微服务只有8001 8002 8003 三台,OK?​ private int total = 0; // 总共被调用的次数,目前要求每台被调用5次 private int currentIndex = 0; // 当前提供服务的机器号​ public Server choose(ILoadBalancer lb, Object key){ if (lb == null) { return null; } Server server = null; while (server == null) { if (Thread.interrupted()) { return null; }​ List<Server> upList = lb.getReachableServers(); List<Server> allList = lb.getAllServers(); int serverCount = allList.size(); if (serverCount == 0) { return null; } if(total < 3){ server = upList.get(currentIndex); total++; }else { total = 0; currentIndex++; if(currentIndex >= upList.size()) { currentIndex = 0; } } if (server == null) { Thread.yield(); continue; } if (server.isAlive()) { return (server); } server = null; Thread.yield(); } return server; } @Override public Server choose(Object key) { return choose(getLoadBalancer(), key); }​ @Override public void initWithNiwsConfig(IClientConfig iClientConfig) {​ }}​ 使用自定义负载均衡策略的方式: 第一种,直接在启动类上添加 @RibbonClient(name = "order-service",configuration = MyRule.class) name指的是服务名称,configuration指的是自定义算法类。 第二种,在配置文件中指定自定义的负载均衡算法类。 # 指定order-service的负载策略user-service.ribbon.NFLoadBalancerRuleClassName=javaer.study.RibbonTest.MyRule ServerList ServerList用于获取服务节点列表并存储的组件。 存储分为静态存储和动态存储两种方式。 默认从配置文件中获取服务节点列表并存储称为静态存储。 从注册中心获取对应的服务实例信息并存储称为动态存储。 ServerListFilter ServerListFilter主要用于实现服务实例列表的过滤,通过传入的服务实例清单,根据规则返回过滤后的服务实例清单。 ServerListUpdater ServerListUpdater是列表更新器,用于动态的更新服务列表。 ServerListUpdater通过任务调度去定时实现更新操作。所以它有个唯一实现子类:PollingServerListUpdater。 PollingServerListUpdater动态服务器列表更新器要更新的默认实现,使用一个任务调度器ScheduledThreadPoolExecutor完成定时更新。 IPing 缓存到本地的服务实例信息有可能已经无法提供服务了,这个时候就需要有一个检测的组件,来检测服务实例信息是否可用。 IPing就是用来客户端用于快速检查服务器当时是否处于活动状态(心跳检测) ILoadBalancer ILoadBalancer是整个Ribbon中最重要的一个环节,它将负载均衡器最核心的资源也就是所有的服务的获取,更新,过滤,选择等操作都能安排的妥妥当当。 packagecom.netflix.loadbalancer;​import java.util.List;​public interface ILoadBalancer { void addServers(List<Server> var1);​ Server chooseServer(Object var1);​ void markServerDown(Server var1);​ /** @deprecated */ @Deprecated List<Server> getServerList(boolean var1);​ List<Server> getReachableServers();​ List<Server> getAllServers();}​ ILoadBalancer最重要的重要是获取所有的服务节点信息,或者是获取可访问的服务节点信息,然后通过ServerListFilter按照指定策略过滤服务节点列表,通过ServerListUpdater动态更新一组服务列表,通过IPing剔除非存活状态下的服务节点以及根据IRule从现有服务器列表中选择一个服务。 Ribbon选择一个可用服务的详细流程 通过上图可知,流程如下: 通过ServerList从配置文件或者注册中心获取服务节点列表信息。 某些情况下我们可能需要通过通过ServerListFilter按照指定策略过滤服务节点列表。 为了避免每次都要去注册中心或者配置文件中获取服务节点信息,我们会将过滤后的服务列表信息存到本地内存。此时如果新增服务节点或者是下线某些服务时,我们需要通过ServerListUpdater来动态更新服务列表。 当有些服务节点已经无法提供服务后,我们会通过IPing(心跳检测)来剔除服务。 最后ILoadBalancer 接口通过IRule指定的负载均衡算法去服务列表中选取一个服务。 Ribbon的使用方式 总体来说Ribbon 的使用方式分为三种 第一种,使用原生API的方式 首先我们创建一个RibbonClient工程,然后创建一个RibbonTest类: RibbonTest package javaer.study.RibbonTest;​import com.netflix.loadbalancer.BaseLoadBalancer;import com.netflix.loadbalancer.LoadBalancerBuilder;import com.netflix.loadbalancer.RandomRule;import com.netflix.loadbalancer.Server;import com.netflix.loadbalancer.reactive.LoadBalancerCommand;import com.netflix.loadbalancer.reactive.ServerOperation;import org.springframework.beans.factory.annotation.Autowired;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 rx.Observable;​import java.util.Arrays;import java.util.List;​/** * 测试Ribbon原生Api用法 * * @author javaMaster*公众号:【Java学习部落】 * @create 2020 09 11 * @Version 1.0.0 */​@RestController@RequestMapping("/ribbon")public class RibbonTest {​// @Autowired// private LoadBalancerClient loadBalancer;​ @Autowired private RestTemplate restTemplate;​ @GetMapping("/test") public String getMsg() {​ //使用Ribbon原生API调用服务 //手动创建服务列表,当然也可以从注册中心中获取到服务列表 List<Server> serverList = Arrays.asList(new Server("localHost", 7777), new Server("localHost", 8888), new Server("localHost", 9999)); BaseLoadBalancer baseLoadBalancer = LoadBalancerBuilder.newBuilder().buildFixedServerListLoadBalancer(serverList);​ //设置负载均衡策略IRule,默认使用轮询,此处我们设置为随机策略 baseLoadBalancer.setRule(new RandomRule()); for (int i = 0; i < 10; i++) { String result = LoadBalancerCommand.<String>builder().withLoadBalancer(baseLoadBalancer).build() .submit(new ServerOperation<String>() { public Observable<String> call(Server server) { try { String addr = "http://" + server.getHost() + ":" + server.getPort(); System.out.println("当前调用的服务地址为:" + addr); return Observable.just(""); } catch (Exception e) { return Observable.error(e); } } }).toBlocking().first(); }​ }}​ 启动项目,访问http://localhost:8008/ribbon/test,运行结果如下: 因为我们设置的IRule是随机策略,所以我们看到访问结果是从服务列表随机获取服务地址进行访问。 第二种,当我们整合了Spring-Cloud时,我们就可以使用Ribbon + RestTemplate来实现负载均衡。 因为我们要实现通过Ribbon + RestTemplate通过指定的负载均衡的策略去选取某一个服务进行调用,所以我们先来创建一个订单服务OrderService。 首先我们在配置文件中添加配置信息; //指定服务名称spring.application.name=order-service//指定EurekaServer的访问地址eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ 接下来创建一个OrderController package javaer.study.controller;​import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;​/** * 订单服务控制类 * * @author javaMaster * 公众号:【Java 学习部落】 * @create 2020 09 12 * @Version 1.0.0 */​@RestControllerpublic class OrderController {​ @Value("${server.port}") private String port; /** * 返回一条消息 */ @GetMapping("/test") public String test() throws InterruptedException { Thread.sleep(3000); return "调用服务的地址的端口为: " + port; }}​ 最后我们在启动类上加上@EnableEurekaClient注解; package javaer.study;​import org.springframework.boot.SpringApplication;import org.springframework.boot.WebApplicationType;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.builder.SpringApplicationBuilder;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;​@SpringBootApplication@EnableEurekaClientpublic class OrderserviceApplication {​ public static void main(String[] args) { new SpringApplicationBuilder(OrderserviceApplication.class).web(WebApplicationType.SERVLET).run(args);​ }}​ 代码部分完成,然后我们启动上一篇文章中搭建的EurekaServer服务。 启动成功后,我们访问http://localhost:8761/,结果如下,我们发现此时并有服务注册到Eureka注册中心。 然后我们在下图处分别配置7777,8888,9999三个端口启动。 然后我们刷新之前打开的http://localhost:8761/页面,我们发现此时已经有三个服务名为order-service,端口号分别7777,8888,9999的服务注册了进来: 好了,多个服务已经搭建好了,接下来,我们就要通过Ribbon+RestTemplate的方式从Eureka注册中心中获取服务列表,并通过负载均衡策略访问指定的服务节点。 第一步,我们依旧使用RibbonClient工程,我们创建一个RestTemplateConfig类来配置RestTemplate实例。 RestTemplateConfig package javaer.study.RibbonTest;​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;​/** * RestTemplate配置类 * * @author javaMaster*公众号:【Java学习部落】 * @create 2020 09 14 * @Version 1.0.0 */@Configurationpublic class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate();}}​ 眼尖的同学肯定已经发现了,我们添加了一个@LoadBalanced注解,添加了该注解后,我们就不需要使用IP+端口的形式去调用服务了,我们可以直接使用服务名并且自带负载均衡功能去调用服务。 最后我们修改RibbonTest代码: package javaer.study.RibbonTest;​import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;​/** * 测试Ribbon原生Api用法 * * @author javaMaster * 公众号:【Java 学习部落】 * @create 2020 09 11 * @Version 1.0.0 */@RestControllerpublic class RibbonTest { @Autowired private RestTemplate restTemplate; @GetMapping("/test") public String getMsg() { String msg = restTemplate.getForObject("http://order-service/test", String.class); return msg; }}​ 最后我们启动RibbonClient项目,由于我们并没有设置负载均衡策略,所以默认使用轮询策略来调度服务。 项目启动成功后,我们访问http://localhost:8008/ribbon/test,刷新三次页面我们,访问结果依次如下: 可能你的访问顺序并不是按照我这个顺序来的,但是一定是三个端口循环调用。 第三种,使用Ribbon+Fegin,这种方式后续会有专文讲解,此处不做多演示。 Ribbon饥饿加载(eager-load)模式 我们在搭建完springcloud微服务时,经常会发生这样一个问题:我们服务消费方调用服务提供方接口的时候,第一次请求经常会超时,再次调用就没有问题了。 为什么会这样? 主要原因是Ribbon进行客户端负载均衡的Client并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的Client,所以第一次调用的耗时不仅仅包含发送HTTP请求的时间,还包含了创建RibbonClient的时间,这样一来如果创建时间速度较慢,同时设置的超时时间又比较短的话,从而就会很容易发生请求超时的问题。 解决方法 既然超时的原因是第一次调用时还需要创建RibbonClient,那么我们能不能提前创建RibbonClient呢? 既然我们都能想到,那么SpringCloud开发者肯定也能想到。 所以我们可以通过设置下面两个属性来提前创建RibbonClient: //开启Ribbon的饥饿加载模式ribbon.eager-load.enabled=true//指定需要饥饿加载的服务名ribbon.eager-load.clients=cloud-shop-userservice Ribbon 总结 本文介绍了Ribbon的使用场景,介绍了Ribbon和Nginx的区别,从Ribbon的整体架构入手,详细介绍了Ribbon的五大组件IRule,IPing,ServerList,ServerListFilter,ServerListUpdater。并且详细说明的负载均衡器的核心接口ILoadBalancer。以及Ribbon的使用方式和Ribbon的饥饿加载模式。 Ribbon负载均衡是SpringCloud生态系统中不可缺少的一环,也是面试中经常会出现的高频面试题。 原创不易,如果大家喜欢,赏个分享点赞在看三连吧。和大家一起成为这世界上最优秀的人。

优秀的个人博客,低调大师

史上最强Dubbo面试26题和答案:核心组件+服务治理+架构设计等

1.Dubbo是什么? Dubbo 是一个分布式、高性能、透明化的 RPC 服务框架,提供服务自动注册、自动发现等高效服务治理方案, 可以和 Spring 框架无缝集成。 RPC 指的是远程调用协议,也就是说两个服务器交互数据。 2.Dubbo的由来? 互联网的快速发展,Web应用程序的规模不断扩大,一般会经历如下四个发展阶段。 单一应用架构:当网站流量很小时,只需一个应用,将所有功能都部署在一起即可。 垂直应用架构:当访问量逐渐增大,单一应用按照有业务线拆成多个应用,以提升效率。 分布式服务架构 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。 此时,用于提高业务复用及整合的 分布式服务框架(RPC) 是关键。 流动计算架构 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。 此时,用于提高机器利用率的 资源调度和治理中心(SOA) 是关键。 3.Dubbo的主要应用场景? 透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。 软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。 4.Dubbo的核心功能? 主要就是如下3个核心功能: Remoting:网络通信框架,提供对多种NIO框架抽象封装,包括“同步转异步”和“请求-响应”模式的信息交换方式。 Cluster:服务框架,提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。 Registry:服务注册,基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。 5.Dubbo的核心组件? 6.Dubbo服务注册与发现的流程? 流程说明: Provider(提供者)绑定指定端口并启动服务; 指供者连接注册中心,并发本机IP、端口、应用信息和提供服务信息发送至注册中心存储; Consumer(消费者),连接注册中心 ,并发送应用信息、所求服务信息至注册中心; 注册中心根据 消费 者所求服务信息匹配对应的提供者列表发送至Consumer 应用缓存; Consumer 在发起远程调用时基于缓存的消费者列表择其一发起调用; Provider 状态变更会实时通知注册中心、在由注册中心实时推送至Consumer。 设计的原因: Consumer 与Provider 解偶,双方都可以横向增减节点数; 注册中心对本身可做对等集群,可动态增减节点,并且任意一台宕掉后,将自动切换到另一台; 去中心化,双方不直接依懒注册中心,即使注册中心全部宕机短时间内也不会影响服务的调用; 服务提供者无状态,任意一台宕掉后,不影响使用。 7.Dubbo的架构设计? Dubbo框架设计一共划分了10个层: 服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现; 配置层(Config):对外配置接口,以ServiceConfig和ReferenceConfig为中心; 服务代理层(Proxy):服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton; 服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心; 集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心; 监控层(Monitor):RPC调用次数和调用时间监控; 远程调用层(Protocol):封将RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter; 信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心; 网络传输层(Transport):抽象mina和netty为统一接口,以Message为中心。 8.Dubbo的服务调用流程? 9.Dubbo支持哪些协议,每种协议的应用场景,优缺点? dubbo: 单一长连接和NIO异步通讯,适合大并发小数据量的服务调用,以及消费者远大于提供者。传输协议TCP,异步,Hessian序列化; rmi: 采用JDK标准的rmi协议实现,传输参数和返回参数对象需要实现Serializable接口,使用java标准序列化机制,使用阻塞式短连接,传输数据包大小混合,消费者和提供者个数差不多,可传文件,传输协议TCP。 多个短连接,TCP协议传输,同步传输,适用常规的远程服务调用和rmi互操作。在依赖低版本的Common-Collections包,java序列化存在安全漏洞; webservice: 基于WebService的远程调用协议,集成CXF实现,提供和原生WebService的互操作。多个短连接,基于HTTP传输,同步传输,适用系统集成和跨语言调用; http: 基于Http表单提交的远程调用协议,使用Spring的HttpInvoke实现。多个短连接,传输协议HTTP,传入参数大小混合,提供者个数多于消费者,需要给应用程序和浏览器JS调用; hessian: 集成Hessian服务,基于HTTP通讯,采用Servlet暴露服务,Dubbo内嵌Jetty作为服务器时默认实现,提供与Hession服务互操作。多个短连接,同步HTTP传输,Hessian序列化,传入参数较大,提供者大于消费者,提供者压力较大,可传文件; memcache: 基于memcached实现的RPC协议; redis: 基于redis实现的RPC协议。 10.dubbo推荐用什么协议? 默认使用dubbo协议。 11.Dubbo有些哪些注册中心? Multicast注册中心: Multicast注册中心不需要任何中心节点,只要广播地址,就能进行服务注册和发现。基于网络中组播传输实现; Zookeeper注册中心: 基于分布式协调系统Zookeeper实现,采用Zookeeper的watch机制实现数据变更; redis注册中心: 基于redis实现,采用key/Map存储,住key存储服务名和类型,Map中key存储服务URL,value服务过期时间。基于redis的发布/订阅模式通知数据变更; Simple注册中心 12.Dubbo默认采用注册中心?采用Zookeeper。 13.为什么需要服务治理? 过多的服务URL配置困难; 负载均衡分配节点压力过大的情况下也需要部署集群; 服务依赖混乱,启动顺序不清晰; 过多服务导致性能指标分析难度较大,需要监控; 14.Dubbo的注册中心集群挂掉,发布者和订阅者之间还能通信么? 可以的,启动dubbo时,消费者会从zookeeper拉取注册的生产者的地址接口等数据,缓存在本地。 每次调用时,按照本地存储的地址进行调用。 15.Dubbo与Spring的关系? Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。 16.Dubbo使用的是什么通信框架? 默认使用NIO Netty框架。 17.Dubbo集群提供了哪些负载均衡策略? Random LoadBalance: 随机选取提供者策略,有利于动态调整提供者权重。截面碰撞率高,调用次数越多,分布越均匀; RoundRobin LoadBalance: 轮循选取提供者策略,平均分布,但是存在请求累积的问题; LeastActive LoadBalance: 最少活跃调用策略,解决慢提供者接收更少的请求; ConstantHash LoadBalance: 一致性Hash策略,使相同参数请求总是发到同一提供者,一台机器宕机,可以基于虚拟节点,分摊至其他提供者,避免引起提供者的剧烈变动;缺省时为Random随机调用。 18.Dubbo的集群容错方案有哪些? Failover Cluster 失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。 Failfast Cluster 快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。 Failsafe Cluster 失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。 Failback Cluster 失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。 Forking Cluster 并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。 Broadcast Cluster 广播调用所有提供者,逐个调用,任意一台报错则报错 。通常用于通知所有提供者更新缓存或日志等本地资源信息。 **19.Dubbo的默认集群容错方案?**Failover Cluster。 20.Dubbo支持哪些序列化方式? 默认使用Hessian序列化,还有Duddo、FastJson、Java自带序列化。 21.Dubbo超时时间怎样设置? Dubbo超时时间设置有两种方式: 服务提供者端设置超时时间,在Dubbo的用户文档中,推荐如果能在服务端多配置就尽量多配置,因为服务提供者比消费者更清楚自己提供的服务特性。 服务消费者端设置超时时间,如果在消费者端设置了超时时间,以消费者端为主,即优先级更高。因为服务调用方设置超时时间控制性更灵活。如果消费方超时,服务端线程不会定制,会产生警告。 22.服务调用超时问题怎么解决? dubbo在调用服务不成功时,默认是会重试两次的。 23.Dubbo在安全机制方面是如何解决? Dubbo通过Token令牌防止用户绕过注册中心直连,然后在注册中心上管理授权。Dubbo还提供服务黑白名单,来控制服务所允许的调用方。 24.dubbo 和 dubbox 之间的区别? dubbox 基于 dubbo 上做了一些扩展,如加了服务可 restful 调用,更新了开源组件等。 25.除了Dubbo还有哪些分布式框架? 大家熟知的就是Spring cloud,当然国外也有类似的多个框架。 26.Dubbo和Spring Cloud的关系? Dubbo 是 SOA 时代的产物,它的关注点主要在于服务的调用,流量分发、流量监控和熔断。而 Spring Cloud 诞生于微服务架构时代,考虑的是微服务治理的方方面面,另外由于依托了 Spirng、Spirng Boot 的优势之上,两个框架在开始目标就不一致,Dubbo 定位服务治理、Spirng Cloud 是一个生态。 27.dubbo和spring cloud的区别?最大的区别:Dubbo底层是使用Netty这样的NIO框架,是基于TCP协议传输的,配合以Hession序列化完成RPC通信。 而SpringCloud是基于Http协议+Rest接口调用远程过程的通信,相对来说,Http请求会有更大的报文,占的带宽也会更多。但是REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖。 以上就是最强Dubbo面试题答案的详解。更多BAT最全面试题目与答案,请参考【最新1000+道Java面试题】: 欢迎留言或进我的个人群179961551(送上图资料),本群专用于探讨交流技术、分享面试机会,拒绝广告,我也会在群内不定期答疑。

优秀的个人博客,低调大师

(牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)

假定一种编码的编码范围是a ~ y的25个字母,从1位到4位的编码,如果我们把该编码按字典序排序,形成一个数组如下: a, aa, aaa,aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx,yyyy 其中a的Index为0,aa的Index为1,aaa的Index为2,以此类推。 编写一个函数,输入是任意一个编码,输出这个编码对应的Index. 输入描述: 输入一个待编码的字符串,字符串长度小于等于100. 输出描述: 输出这个编码的index 示例1 输入 baca 输出 16331 题目解析点击进入 JAVA import java.util.*; public class Main { public static int number(String str) { int add = str.length()-1;//要考虑到字符串的长度 int mul1 = 1 + 25 + 25*25 + 25*25*25;//从左往右,第一位(进位所需要乘以的数值) int mul2 = 1 + 25 + 25*25;//第二位 int mul3 = 1 + 25;//第三位 int mul4 = 1;//第四位 int[] mul = new int[4];//把上面的四个数放到数组里,以便在下面的循环中使用 mul[0] = mul1; mul[1] = mul2; mul[2] = mul3; mul[3] = mul4; char[] ch = str.toCharArray(); int result = 0; for(int i = 0;i < ch.length;i++) { result += (ch[i] - 'a')*mul[i]; } result += add;//最后把长度考虑进去,不然会出现错误,比如a和aa都会返回0 return result; } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String str = scanner.next(); scanner.close(); int result = number(str); System.out.println(result); } } C /* * 五笔编码 * * 五笔的编码范围是a ~ y的25个字母,从1位到4位的编码,如果我们把五笔的编码按字典序排序,形成一个数组如下: * a, aa, aaa, aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx, yyyy * 其中a的Index为0,aa的Index为1,aaa的Index为2,以此类推。 * 编写一个函数,输入是任意一个编码,比如baca,输出这个编码对应的Index; * 编写一个函数,输入是任意一个Index,比如12345,输出这个Index对应的编码。 */ void WubiIndex(const string &input) { const int NUM = 25; const char* p = input.c_str(); int index = 0; int N = 3; int SUM[4] = {1}; for(int i = 1; i < 4; ++i) SUM[i] = NUM * (SUM[i-1]) + 1; while(*p) { int temp = 0; index += (*p -'a')*SUM[N--]; ++p; } cout<<"index is "<<index<<endl; } void WubiCoding(int index) { const int NUM = 25; int SUM[4] = {1}; for(int i = 1; i < 4; ++i) SUM[i] = NUM * (SUM[i-1]) + 1; char ch[5] = {'\0'}; int N = 3; int M = 0; while(index > 0) { ch[M++] = 'a' + (index - 1)/SUM[N]; index = (index - 1)%SUM[N--]; } cout<<"string is "<<ch<<endl; }

优秀的个人博客,低调大师

大数据的道理你都懂,但是这道应用题你敢不敢做?

你有没有听说前几天百度老大李彦宏把一辆无人驾驶汽车开上了五环?最近还传说,iPhone8可能使用人脸识别解锁技术。这些从前听起来如同不着边际还有点扯的想法在短短几年内开始一桩桩变成现实,或者说,再过几年,这些如今的黑科技就要接管我们的生活了。 正在看文章的朋友,你的生活都要被大数据和人工智能接管了,还不赶紧来听一场行业顶尖的大数据峰会吗? 10场大数据专题论坛,16项大数据专业议题,60余位行业顶尖嘉宾,7月13日到14日,“2017中国大数据应用大会”即将亮相成都世纪城国际会议中心。无论你是行业资深人士,还是外圈好奇小白,这场满满干货的盛会都会带给你无限思考与启发! 此次大会以“大数据、大智能、大健康”为主题。对于大多数人来说,大数据都已经不是一个全新概念了。但是这个词究竟会以什么方式对我们的生活带来多大改变,这个问题恐怕大多数人都还没有答案。 先不说网购、移动通讯和智能家居这些话题,现在你出门走个几千步,都迫不及待地同步到微信运动,顺手也在蚂蚁森林里收收昨天的运动能量。大数据这个词听起来高端又遥远,但其实它早就悄悄潜入了你的生活,把你的运动数据、消费数据、通讯数据打包在一起,在信息时间里猜测你的所思所想,然后把它们在合适的时机送到你的生活中。 要实现这些愿望,云计算、物联网与大数据技术开始深度融合,大数据采集、存取、计算等环节的技术水平正在稳步提升,使得大数据应用的门槛降低、成本减少,而自然语言理解、机器学习、深度学习等人工智能技术与大数据技术融合,有效地提升数据分析处理能力、知识发现能力和辅助决策能力,让大数据成为人类认识世界、推动智能化的有效工具。 智能驾驶、环境治理、数字化转型、人工智能、政务大数据、数据安全,这些大数据应用早已经跳出了单纯的大数据圈子,开始进入大家日常谈论的话题范畴,而同样,这些话题也成为了这次大会所关心的方向。 和你一起讨论这些话题的人会有谁? 将要在大会上分享行业洞见的顶尖大咖团可谓含金量十足,其中既有中国科学院院士郭华东 、中国工程院院士方滨兴、谭建荣等学界精英分享最前沿的研究成果,还有京东云、INTEL、IBM、科大讯飞等改变着你的日常生活的科技公司大佬们为你带来最前沿的大数据应用秘籍。 此外,大会还邀请了众多知名公司高管、白宫信息物理系统顾问李杰,以及美国前总统奥巴马竞选团队首席技术官Harper Reed等这些恐怕平时只能在美剧里、新闻里稍稍了解的神秘人物这次都在成都等着你了。 所以,如果说在其他大数据峰会上,你能看到的是国内大数据行业大牛们的交锋,那么七月中旬的成都带给你的一定是场国际级的思维碰撞。 大会精彩看点 No.1 风口上的健康医疗 自从医生从手写病历到电脑录入,大量医院开始实现医疗信息化,但是真正实现数据互通的医院则寥寥无几。如何破除医疗机构的信息孤岛,将医疗数据整合起来,成了行业专家无比关心的问题。健康医疗也成为了大数据时代的一个巨大风口。此次大会上,你将听到国家健康医疗大数据中心及产业园建设的顶层设计以及最前沿的试点经验。同时,他们还会重点讨论健康医疗数据中至关重要的一环——信息安全。 No.2当人工智能进入商业领域,会发生什么? 从今年年初的大胜全球围棋顶级高手,到最近击败了人类围棋的最强战士柯洁,AlphaGo在短短三年中用海量数据的积累和超强的学习能力超越了人类围棋巅峰。那么,当人工智能遇上大数据,又会发生什么呢?对于普通人来说,人工智能已经开始改变你的剁手方式,而对于企业来说,AI 又能做些什么?处理器行业元老 Intel想在这次盛会上帮助各个领域的商业精英们以人工智能为企业赋能,最大化他们的商业价值,用全新的方式探寻企业的无限潜力。 No.3无人驾驶这么火,智能汽车企业活得怎么样? 百度老大李彦宏刚刚坐着没有人驾驶的汽车上了北京五环,于是一个属于无人驾驶和智能汽车的时代也即将到来了。在智能汽车的发展里,大数据如何影响产业的方方面面,互联网巨头将从汽车行业之外的角度给你一个全新的视角,而另一方面,传统汽车领域佼佼者要转型杀入智能汽车领域是一种怎样的体验,老牌车企们也将为你娓娓道来。 此外,从政府的角度来说,在道路上出现越来越多没有司机的汽车时,要如何建设一个成熟的无人驾驶系统,如何规范本地化智能汽车产业的发展,都是亟待解决的问题。而这些解决方案都需要在与车企和互联网企业的商议中逐渐成型。 No.4 银行 VS BAT,金融行业的两种选择 金融行业自出现之日起,就自带大数据基因,信息化程度高,数据质量好,数据维度全,数据场景多,这些特点成为了金融行业的先天优势。 马云爸爸在让全国女性为之剁手了多年,同时他也带来了改变中国金融征信体系的蚂蚁金服。于是,和众多其他行业一样,金融领域也开始被互联网巨头们慢慢改造,在这之中会发生什么变化,互联网黑科技又要如何为金融这一传统领域带来新的生机呢? 而在互联网公司进入金融市场的同时,传统金融企业也做出了自己的回应。他们正在利用大数据改变自己的管理模式和发展策略。至于他们是如何做到的,你都可以在会场上一探究竟。 No.5不管你是否从事大数据工作,你的工作早已经被数据化了 当你在面试中回答 HR 的一系列问题时,当老板把你叫到办公室里聊绩效时,你有没有想过,他们这些问题的基础并不仅仅是一个个平日经验构成的“我觉得”,或者惯性思维中的“大概吧”。他们脑海中的资料大部分来源于人力资源大数据。这些大数据技术的出现正在改变企业对人才能力的评估。企业具体是如何用大数据来进行员工招聘、人才测评、团队管理的?这些问题都会在此次大会上得到答案。 No.6听腻了传统教育改革,现在的智能教育真还不一样 当大数据的风潮席卷中国,所有人都在聊如何商业应用,而这次有一群人想和你聊聊,大数据将如何改变中国教育行业。他们见证着中国教育的改革和发展历程。看到了智慧教育在其中面临的挑战。同时,他们还在各个学校里尝试着智慧教育的一切可能性,想知道,大数据时代的中小学教育应该是个什么样子。 这些教育行业的践行者都在卯足了劲告诉你,自从遇到大数据,教育行业早就不是你原来认识的那个教育行业了。 No.7 智媒体时代已经到来,你们每天的阅读体验将如何被定义? 智能+媒体,一个强理性产物和一个追求内容和表达的领域要如何兼容?也许一两年前,我们讨论的还是华尔街日报的智能写作机器人会不会取代传统媒体人的职位。然而现在,当人工智能已经开始被应用在媒体工作的诸多环节,我们在使用同一产品时,看到的却是基于我们的阅读习惯而高度定制化的内容,于是我们关心的问题也转变成了,智媒体时代产生了哪些舆论场挑战,以及其中的大数据策略。内容平台、互联网企业,以及学界大佬都将参与到这场关于媒体和读者未来的讨论中来,相信你一定不想错过这场智媒体时代的头脑风暴。 No.8 黑科技博览会 听完了干货满满的嘉宾分享后,还要做些什么呢?在成都世纪城新国际会展中心2号馆将有各种各样狂拽酷炫的黑科技展览等着你。人脸识别、深度学习、无人驾驶、智能制造、AR/VR,在这些黑科技正式来敲你家大门之前,还是先来展区里和它们混个脸熟吧。 原文发布时间为:2017年7月10日 本文来自云栖社区合作伙伴至顶网,了解相关信息可以关注至顶网。

优秀的个人博客,低调大师

创业之初的技术题:如何构建一个较为通用的业务技术架构

1、通用架构概述 创业之初,我们往往会为了快速迭代出产品,而选择最简单的技术架构,比如LAMP架构,SSH三层架构。这些架构可以适应初期业务的快速发展,但是,随着业务变得越来越复杂,我们会发现这些架构越来越难支撑业务的发展,出现在一个类中写好几千行代码,一个方法中到处都是if else语句,如果中间遇到主程序猿离职,后面介入的程序猿几乎无法理解这些代码,到最后,产品越来越难迭代,只能推翻重做。如果我们在创业初始就以一种适应性较强的架构去写代码,后面就会少走很多弯路。下面的文章是我自己总结出来的一套架构,经过实践,适应性还算不错。 2、通用架构实现 总的来说我的通用架构还是以三层架构为基础进行演变的,在经典的三层架构中,最上层的是controller,中间是service,下层是dao。在我的架构中,最上层是网关层,controller只是网关的一种,中间是业务层,service只是业务层的入口,最下层是基础层,dao只是基础层中的数据存储组件。 2.1、网关层 网关层本质上是对不同的网络协议的请求进行处理,比如HTTP协议,TCP协议,当然,也可以对其他协议进行处理。具体见下图: 2.1.1、HTTP请求 一般来自PC端和APP端的请求都是基于HTTP协议的,对于处理HTTP请求的方案,业内已经非常成熟了。首先,tomcat容器本身已经把HTTP请求处理的复杂性封装掉了,其次,spring mvc对请求处理提供了RESTful风格的编码方式,大大降低了开发的复杂度。我们要做的就是对controller按照业务领域划分,比如按照订单、会员去划分大的领域,里面的各种方法就是这个领域内的操作。这里的controller就是统一网关处理层,对于每个controller的方法只做三件事,第一,将请求参数解析出来并组装成内部参数,第二调用下层服务执行业务逻辑,第三组装返回结果,对于异常情况,需要记录异常堆栈日志并转换错误码,堆栈信息不要暴露到调用方。 2.1.2、TCP请求 对于处理TCP请求的方案,业内也已经很成熟了,比如Netty。但是,TCP请求毕竟太底层,我们往往会基于TCP协议去开发自己的协议。另外,很多分布式框架都是基于TCP协议的,比如RPC框架Dubbo,消息框架RocketMQ等等。从单机系统到分布式系统,无非就是网关层多了处理TCP请求的逻辑,理论上底层的业务是无需感知自己到底是出于单机环境还是分布式环境,网关层的作用就是要屏蔽这种不同外部调用源的细节。在Dubbo服务端中,我们需要实现远程接口,并对远程服务调用进行内部的转发,转发的逻辑也很简单,首先是解析参数并组装内部参数,然后调用业务层的接口执行业务逻辑,最后组装返回结果,对于异常处理也需要在这里做掉,防止异常暴露给外部应用。 2.1.3、小结 网关层本质是对协议进行处理,同时将业务逻辑收敛到网关层,而不是暴露给外部,当内部业务逻辑进行重构的时候,外部调用方就不需要感知这些变化,当外部调用源增加时,内部业务逻辑不需要感知这种变化,从而将外部调用方和内部业务逻辑进行了解耦。 2.2、业务层 业务层是一个系统,无论是单机系统还是分布式系统群中的某个业务系统,业务层都是承载业务流程和规则的地方。业务层从外到内包含三层:第一层是业务服务,第二层是业务流程,第三层是业务组件。具体如下图: 2.2.1、业务服务 业务服务是业务层对外的统一门面,它由三方面组成:业务接口、入参、出参。 a) 业务接口 一个业务接口代表一个领域的业务服务,比如订单域的业务服务就由接口OrderService表示,会员域的业务服务就由接口MemberService表示。接口可以按照执行性质分为读接口和写接口,比如OrderReadService和OrderWriteService。读写分离的好处是可以对集群进行读写分组,从而管理流量,当然,单机系统读写分离意义不是太大。领域内的操作则以业务接口中的方法的形式体现,比如订单域有下单createOrder,取消订单cancelOrder等等操作。对于这些操作,尽量设计出有业务含义的方法,而不是增删改查,当然,对于一些简单的业务,也只能增删改查。 b)入参 接下来,是入参的设计。入参对于读方法,比较简单,不做讨论。对于写方法,我们将入参设计成有层次的数据模型。首先需要设计出公共的数据模型,比如订单数据模型,商家数据模型,商品数据模型等,然后将这些数据模型和一些特定业务下的个性数据结合,组成Request对象,这个request对象按照不同业务操作不同而不同,对应的返回结果就是response,它也是随着不同业务返回的参数不同。 举个例子,拿下餐饮订单来说,首先,我们应该识别出这些业务流程中一些比较基础的数据模型,比如餐饮领域的菜品、桌位等,这些模型之所以说是基础模型,是因为,不管下什么餐饮订单,菜品和桌位肯定是逃不了的,它们是可以被复用的!因此,我们分别为这些基础模型设计相对于的DO(Domian Object):DishDO(菜品)、BoardDO(桌位)等等,接下来,我们为下餐饮订单设计一个请求对象DishOrderCreateRequest其中DishOrderCreateRequest内部包含了DishDO和BoardDO,另外会包含一些特定的属性,比如人数啊,折扣啊等等,这样一来就能做到通用和灵活兼顾,DishOrderCreateRequest代表的个性化的灵活的业务入参,而DishDO和BoardDO等则代表了不易变化的基础模型。 c) 出参 最后,是出参的设计。对于写方法,一般出参比较简单。对于读方法,出参往往是一个结构与层次比较复杂的组合对象。比如查询一个订单,这个订单有订单基本信息,还有商品信息,收货人地址信息等。在设计出参的时候,结构上要设计成组合对象,但是真正查询的时候,通过查询选择器,去查询不同的组合对象。比如查询选择器设置商品查询为true,地址查询为false,那么这次查询出的订单就只包含商品,而不包含地址。 2.2.2、业务流程 业务流程其实就是对业务规则的解释,只是这种解释使用代码去实现的,我们要做的其实就是准确翻译这些业务规则,并维护好这些业务规则。 业务流程中可以大致分为三种动作节点,1、组装参数节点 2、规则判断节点 3、执行动作节点,其中每个动作节点都是一些业务代码的片段。举个例子,下餐饮订单,我们第一步就是将上层传入的参数组装出一个基础的DishOrderDO(组装参数节点),然后按照特定的规则去填充这个DishOrderDO(规则判断节点),然后就是调用DAO去创建DishOrderDO(执行动作节点)。 业务流程是最容易变化的地方,要想维护好业务流程并不容易,总的思想是将大的业务流程拆分成小的业务流程,抽出每个业务流程中共有的代码片段,变成可维护的业务组件。 2.2.2、业务组件 a) 基础组件 业务组件其实是将一些内聚的可复用的代码片段进行封装。和业务流程中的三种业务节点相对应,业务组件也分为三种:组装参数组件、规则判断组件、动作执行业务组件。业务组件的抽象往往是对业务有了深刻理解之后才进行的,盲目地进行业务组件的抽象,往往到头来白忙活。 b) 能力 对业务组件进行进一步抽象,可以得到能力。业务能力是具有一定复用性的组件的组合,比如发短信能力=组装短信参数组件+发短信组件。对于发短信能力,可以被不同的业务流程复用,比如订单下单成功发短信,支付成功发短信,逻辑都是相似的,只有内容不同。能力是一种粒度比较大的组件,粒度越大,往往复用性就越小,对能力的抽取,也是基于对特定业务深刻的理解,没有一劳永逸的银弹。 c)更高纬度的抽象 经过本人的实践,对于互联网这样的需求变化极快的场景,更高纬度的组件抽象往往性价比很低,不建议大家去做。 2.3、基础层 基础层包含两个部分,第一是接口定义,第二是技术组件。 2.3.1、接口定义 接口定义是按照不同的技术框架,同时结合业务需要,设计出合理的接口,对于业务组件来说,它们只会感知技术接口,而不会去感知技术实现,我们也不应该将具体的技术细节向上暴露,这也就是所谓的面向接口编程。技术接口往往是业务与技术之间的桥梁,接口本身是含有业务含义的,最常见的就是DAO接口,我们设计DAO接口的时候,不会设计成insert、update、query这样业务无关的接口,而是设计成insertUser,updateUserById等等和业务相关的接口,同样的道理,设计缓存接口的时候,也不能设计成put、get这样的接口,而应该设计成cacheUser,deprecateUser这样的接口。 2.3.2、技术组件 单机系统的技术组件一般来说分两种,一种是通用的技术组件,比如:数据存储、缓存、消息和调度任务、事务、锁。一种是基础设施,比如spring容器,tomcat容器。下面稍微谈谈通用技术组件。 数据存储:数据存储包括关系型数据库、非关系型数据库以及文件存储系统。关系型数据库,比如MySQL,适合存放绝大部分业务数据。非关系型数据库,比如hbase,可以存放历史日志,也可以对历史的MySQL数据进行归档。文件存储系统,一般都是基于Linux文件系统,比如图片、html文件等等,也有基于HDFS的,用于大数据分析。 缓存:缓存按响应时间分,可以分为纳秒级缓存,毫秒级缓存和百毫秒级缓存。纳秒级缓存就是一般的基于本地内存的缓存,比如encache,毫秒级缓存一般是集中式的内存缓存,比如memcache,由于访问时远程调用,因此响应时间会延长到几毫秒,百毫秒级缓存一般是集中式可持久化的缓存,比如redis,由于存在远程访问以及缓存击穿导致的读取持久化记录,它的响应时间会更长些,到几十甚至上百毫秒。单机系统一般用本地内存缓存就够了,当缓存被击穿的时候,直接访问数据库。 消息和调度任务:消息和调度任务本质都是一种异步化的手段,区别在于消息无法控制异步的时间,而调度任务可以。一般,消息发送出去后,监听消息的系统会立即收到消息,从而立即触发业务逻辑的执行,而调度任务则会按照调度规则,一次或者多次的执行业务逻辑。单机系统中消息和调度任务用到的比较少,在做日志监控的时候可能会用到消息,在进行数据报表统计的时候可能会用到调度任务。 事务:事务本质都是基于数据库去实现的,单机系统的事务就是依赖数据库的事务,我们可以使用spring-tx的事务模板进行事务操作,在业务逻辑开发中,一定要把握事务的大小,建议把业务比较紧密的一堆数据库操作放在一个事务里,不要随意的为每个方法都开启事务。 锁:单机系统中主要用到两种锁:乐观锁和悲观锁。乐观锁依靠在数据库的业务表加版本字段来实现,每次更新都会去判断版本是否变化,如果变化则需要重试,这种锁的粒度比较小。悲观锁是基于JDK的Lock接口的,对一个业务流程进行加锁和释放锁的操作,锁的粒度比较粗。 3、总结 以上是我经过很长一段时间的实践后摸索出来的业务技术架构,自认为还算通用,而且能够在一定程度上支撑易变的业务。当然这套架构肯定不是银弹,不可能解决所有业务场景,所以最终还是需要围绕到具体的场景加以借鉴。 作者:吴极心 来源:51CTO

优秀的个人博客,低调大师

CCAH-CCA-500-6题:You want YARN to launch no more than 16 containers per...

6.What should you do?Each node in your Hadoop cluster, running YARN, has 64GB memory and 24 cores. Your yarn.site.xml has the following configuration:<property><name>yarn.nodemanager.resource.memory-mb</name><value>32768</value></property><property><name>yarn.nodemanager.resource.cpu-vcores</name><value>12</value></property>You want YARN to launch no more than 16 containers per node. What should you do? A.Modify yarn-site.xml with the following property: <name>yarn.scheduler.minimum-allocation-mb</name> <value>2048</value>B.Modify yarn-sites.xml with the following property: <name>yarn.scheduler.minimum-allocation-mb</name> <value>4096</value>C.Modify yarn-site.xml with the following property: <name>yarn.nodemanager.resource.cpu-vccores</name>D.No action is needed: YARN’s dynamic resource allocation automatically optimizes the node memory and cores 问题: Hadoop集群的每台节点内存64G,CPU 24核。当前一个节点可分配的物理内存总量是32768M(32G),可分配的虚拟cpu总个数是12。 那么yarn在每个节点上,发起不超过16个容器,我们应该怎样配置? 分析:A yarn.scheduler.minimum-allocation-mb:最小可申请内存量,默认是1024,我们设置2048M,见如下计算公式 Maximum memory YARN can utilize on the node ————————————————————————————————————————————— = minimum memory per container Number of containers 配置文件 配置项名称 配置项值yarn-site.xml yarn.nodemanager.resource.memory-mb = Containers个数* 每个Container内存yarn-site.xml yarn.scheduler.minimum-allocation-mb = 每个Container内存yarn-site.xml yarn.scheduler.maximum-allocation-mb = Containers个数* 每个Container内存mapred-site.xml mapreduce.map.memory.mb = 每个Container内存mapred-site.xml mapreduce.reduce.memory.mb = 2 * 每个Container内存mapred-site.xml mapreduce.map.java.opts = 0.8 * 每个Container内存mapred-site.xml mapreduce.reduce.java.opts = 0.8 * 2 * 每个Container内存yarn-site.xml (check) yarn.app.mapreduce.am.resource.mb = 2 * 每个Container内存yarn-site.xml (check) yarn.app.mapreduce.am.command-opts = 0.8 * 2 * 每个Container内存 http://developer.51cto.com/art/201401/426610.htm

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册