springboot与分布式

Dubbo/Zookeeper

Zookeeper

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

Docker安装

参考文档https://hub.docker.com/_/zookeeper

1
docker pull zookeeper

默认有3个端口。客户端2181,follow2888,election 3888

1
docker run --name ZK01 -p 2181:2181 --restart always -d zookeeper

Dubbo

Dubbo(读音[ˈdʌbəʊ])是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 [1] Spring框架无缝集成。Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

使用

参考文档https://github.com/apache/dubbo

  • 消费者

    引入依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.3</version>
    </dependency>
    <!-- zookeeper客户端 -->
    <dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>2.7.1</version>
    </dependency>

    新建生产者的接口(不需要实现类,但所在包名要一致)使用@Reference来引用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Service
    public class UserService {


    @Reference
    TicketService ticketService;


    public void hello(){
    System.out.println("卖掉平"+ticketService.getTicket());
    }
    }

    与安卓的AIDL方式很像,一样需要拿到与生产者包名一致的接口即可

  • 生产者

    引入依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.7.3</version>
    </dependency>
    <!-- zookeeper客户端 -->
    <dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>2.7.1</version>
    </dependency>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import org.apache.dubbo.config.annotation.Service;
    import org.springframework.stereotype.Component;

    /**
    * @author Sun
    * @date:11:15 2019/9/30
    * @description: 编写需要远程调用的服务,这里的@Service是dubbo的注解,指定改服务为暴露服务
    */
    @Component
    @Service
    public class TicketServiceImpl implements TicketService {
    @Override
    public String getTicket() {
    return "买到票啦";
    }
    }

    配置zookeeper信息

    1
    2
    3
    4
    5
    6
    7
    dubbo:
    application:
    name: dubbo
    registry:
    address: zookeeper://x.x.x.x:2181
    scan:
    base-packages: com.sun.dubbo.providerticket.service

    遇到的问题

    • 我是整合在springboot中,所以引入的依赖是

    org.apache.dubbo
    dubbo-spring-boot-starter
    2.7.3
    • Caused by: java.lang.ClassNotFoundException: org.apache.curator.framework

      没有引入curator的依赖


      org.apache.curator
      curator-recipes
      2.7.1
    • 无需引入zkClient。

    • 版本要一致starter在2.7就是使用2.7的curator,recipes包含了framework和client。

SpringBoot/Spring Cloud

Spring Cloud 是一套完整的微服务解决方案,基于 Spring Boot 框架,准确的说,它不是一个框架,而是一个大的容器,它将市面上较好的微服务框架集成进来,从而简化了开发者的代码量。spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。

SpringCloud分布式开发五大组件

与dubbo不一样的是,dubbo是基于rpc通信,而springcloud是基于http restful api通信

  • 服务发现——Netflix Eureka
  • 客服端负载均衡——Netflix Ribbon
  • 断路器——Netflix Hystrix
  • 服务网关——Netflix Zuul
  • 分布式配置——Spring Cloud Config

Eureka与Zookeeper区别

CAP

  • C:Constistency(强一致性)
  • A:Availability(可用性)
  • P:Partition tolerance(分区容错性)

Eurka保证的是AP

Zookeeper保证是的CP

参考https://www.cnblogs.com/zgghb/p/6515062.html

负载均衡算法

1、轮询法

  将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载。

2、随机法

通过系统的随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。由概率统计理论可以得知,随着客户端调用服务端的次数增多,

其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮询的结果。

3、源地址哈希法

源地址哈希的思想是根据获取客户端的IP地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客服端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。

4、加权轮询法

  不同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端。

5、加权随机法

与加权轮询法一样,加权随机法也根据后端机器的配置,系统的负载分配不同的权重。不同的是,它是按照权重随机请求后端服务器,而非顺序。

6、最小连接数法

最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有快有慢,它是根据后端服务器当前的连接情况,动态地选取其中当前

积压连接数最少的一台服务器来处理当前的请求,尽可能地提高后端服务的利用效率,将负责合理地分流到每一台服务器。

Ribbon Feign Nginx 有什么区别

  • Ribbon是实现的一套客户端 负载均衡工具,主要提供客户端的负载均衡算法,Ribbon的负载均衡属于进程的负载均衡,让消费端去选择。而Nginx是集中式的负载均衡,在消费端和服务端中间提供负载均衡,消费端直接访问Nginx

    IRule

    实现IRule即可更换Ribbon的lb算法

    具体实现类有

  • Fegin是一个声明式的webService客户端,可以让编写WebService客户端更简单,它的使用方法是定义接口,加上注解。SpringCloud对Fegin进行了封装,使其支持了Spring MVC注解和HttpMessageConverters,Fegin可以与Eureka和Ribbon组合使用支持负载均衡,通过接口的方式去调用

Hystrix

  • 服务熔断

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @GetMapping("/hystrix_test/{id}")
    @HystrixCommand(fallbackMethod = "wrongRespons")
    public String hello(@PathVariable("id") Integer id){
    if(id==1)
    throw new RuntimeException();
    List<AuthApp> authApps = authAppMapper.selectByExample(new AuthAppExample());
    return "hello from api - hystrix";
    }

    public String wrongRespons(@PathVariable("id" ) Integer id){
    return "sorry you are not enter id";
    }
  • 服务降级