乐趣区

关于springboot:微服务分布式协作框架tridenter使用介绍

tridenter是一款基于 SpringBoot 框架开发的微服务分布式合作框架,它能够使多个独立的 SpringBoot 利用轻松快捷地组成一个集群,而不依赖内部的注册核心(比方 SpringCloud Eureka 等)。
tridenter框架首先提供了丰盛的分布式应用集群治理 API 和工具,同时也提供了一套残缺的微服务治理性能

tridenter 的个性:

  1. 采纳去中心化的思维治理集群
  2. 反对集群间的音讯多播和单播
  3. 反对各种负载平衡策略
  4. 反对多种 Leader 选举算法
  5. 提供过程池 / 调度过程池的实现
  6. 内置注册核心
  7. 内置多种微服务间调用的限流降级策略
  8. 内置微服务 Rest 客户端
  9. 内置 HTTP 服务网关
  10. 集群状态监控和告警

集群中的音讯多播是 tridenter 十分重要的性能,tridenter 底层是通过 Redis(PubSub)实现多播性能从而实现利用的互相发现的,进而组成利用集群的。集群中的每个成员都反对音讯多播和单播的能力。
利用 tridenter 反对音讯单播的能力,tridenter 提供了 Leader 选举算法接口,内置了两种 Leader 选举算法,疾速 Leader 选举算法(基于 Redis 队列)和一致性选举算法 (基于 Paxos 算法)
同时,利用 tridenter 反对音讯单播的能力,tridenter 提供了过程池,实现了跨过程的办法调用和办法分片的能力
另一方面,tridenter 自身也提供了微服务治理的基本功能:
tridenter 自带注册核心,而利用音讯多播的原理,利用是互相发现,互相注册的,所以集群中的每个成员都有一份全量的成员列表,即每个利用都是注册核心,体现了去中心化的设计思维。每个成员通过命名服务,实现了利用之间 HTTP 接口相互调用的能力,并提供了相干各种注解和 Restful 配置将服务公布方和生产方解耦
tridenter 自带网关性能,能够将利用独立公布成网关服务,可代理散发 HTTP 申请和下载工作(暂不反对上传)
tridenter 还内置了多种负载平衡算法和限流降级策略,用户也能够自定义负载平衡算法或降级策略
tridenter 实现了 spring actuator 的健康检查接口,除了监控集群状态,还自带接口的统计分析等性能,初步实现了接口的对立治理和监控
所以,基于 tridenter 框架,咱们也能够搭建一套相似于 Spring Cloud 的微服务体系

tridenter 采纳了去中心化的设计思维,即开发人员不须要晓得以后哪个是主节点,哪些节点是从节点,更不应该显式地定义某个利用为主节点,这是由 tridenter 采纳的 Leader 选举算法决定的,默认的选举算法是疾速选举算法。依据选举算法,集群内的任意一个利用节点都有可能成为主节点,默认第一个启动的利用就是主节点,然而如果采纳的是一致性选举算法,可能就会不一样。依据作者形容,一致性选举算法目前不稳固,举荐在利用中应用疾速选举算法。

Maven:

        <dependency>
            <groupId>com.github.paganini2008.atlantis</groupId>
            <artifactId>tridenter-spring-boot-starter</artifactId>
            <version>1.0-RC2</version>
        </dependency>

tridenter 的基本功能就是让不同的 Spring Boot 利用变成集群模式,所以配置的时候,咱们要在 application.properties 定义两个零碎变量,否则会报错

spring.application.name=chaconne-management  # 服务名称
spring.application.cluster.name=chaconne-management-cluster  #集群名称

启动之后,如果在 Console 看到以下信息则示意集群配置失效

2021-06-05 18:20:11 [INFO] io.undertow - starting server: Undertow - 2.0.29.Final
2021-06-05 18:20:11 [INFO] org.xnio - XNIO version 3.3.8.Final
2021-06-05 18:20:11 [INFO] org.xnio.nio - XNIO NIO Implementation Version 3.3.8.Final
2021-06-05 18:20:11 [INFO] i.a.f.t.m.ApplicationMulticastGroup - Registered candidate: {applicationContextPath: http://192.168.159.1:6543, applicationName: chaconne-management, clusterName: chaconne-management-cluster, id: fafdc9ada3a5d1de3836b1a0ba4ef174, leader: false, startTime: 1622888405582, weight: 1}, Proportion: 1/1
2021-06-05 18:20:11 [INFO] i.a.f.t.m.ApplicationRegistryCenter - Register application: [{applicationContextPath: http://192.168.159.1:6543, applicationName: chaconne-management, clusterName: chaconne-management-cluster, id: fafdc9ada3a5d1de3836b1a0ba4ef174, leader: false, startTime: 1622888405582, weight: 1}] to ApplicationRegistryCenter
2021-06-05 18:20:11 [INFO] i.a.f.c.SerialDependencyListener - SerialDependencyHandler initialize successfully.
2021-06-05 18:20:11 [INFO] i.a.f.t.e.ApplicationLeaderElection - This is the leader of application cluster 'chaconne-management-cluster'. Current application event type is 'indi.atlantis.framework.tridenter.election.ApplicationClusterLeaderEvent'
2021-06-05 18:20:11 [INFO] i.a.f.t.e.ApplicationLeaderElection - Current leader: {applicationContextPath: http://192.168.159.1:6543, applicationName: chaconne-management, clusterName: chaconne-management-cluster, id: fafdc9ada3a5d1de3836b1a0ba4ef174, leader: true, startTime: 1622888405582, weight: 1}
2021-06-05 18:20:11 [INFO] o.s.b.w.e.u.UndertowServletWebServer - Undertow started on port(s) 6543 (http) with context path ''
2021-06-05 18:20:12 [INFO] i.a.f.c.m.ChaconneManagementMain - Started ChaconneManagementMain in 12.134 seconds (JVM running for 12.829)

首先:

2021-06-05 18:20:11 [INFO] i.a.f.t.m.ApplicationMulticastGroup - Registered candidate: {applicationContextPath: http://192.168.159.1:6543, applicationName: chaconne-management, clusterName: chaconne-management-cluster, id: fafdc9ada3a5d1de3836b1a0ba4ef174, leader: false, startTime: 1622888405582, weight: 1}, Proportion: 1/1
2021-06-05 18:20:11 [INFO] i.a.f.t.m.ApplicationRegistryCenter - Register application: [{applicationContextPath: http://192.168.159.1:6543, applicationName: chaconne-management, clusterName: chaconne-management-cluster, id: fafdc9ada3a5d1de3836b1a0ba4ef174, leader: false, startTime: 1622888405582, weight: 1}] to ApplicationRegistryCenter

这两行日志别离示意胜利注册音讯多播组和利用注册核心

2021-06-05 18:20:11 [INFO] i.a.f.t.e.ApplicationLeaderElection - This is the leader of application cluster 'chaconne-management-cluster'. Current application event type is 'indi.atlantis.framework.tridenter.election.ApplicationClusterLeaderEvent'
2021-06-05 18:20:11 [INFO] i.a.f.t.e.ApplicationLeaderElection - Current leader: {applicationContextPath: http://192.168.159.1:6543, applicationName: chaconne-management, clusterName: chaconne-management-cluster, id: fafdc9ada3a5d1de3836b1a0ba4ef174, leader: true, startTime: 1622888405582, weight: 1}

这两行日志别离示意利用 ApplicationLeaderElection 选举算法选出以后的利用是 leader,(疾速选举算法默认将第一个启动的利用作为 Leader, 有点相似 Jgroups)

tridenter-spring-boot-starter 是一个根底型的框架,提供了各种分布式能力,上面介绍一下几种能力:

过程池

多个同名利用(${spring.application.name})能够组建成一个过程池,就像线程池调配不同的线程调用某个办法一样,过程池能够进行跨利用的办法调用,前提是这个办法是存在的

示例代码:

    @MultiProcessing(value = "calc", defaultValue = "11")
    public int calc(int a, int b) {if (a % 3 == 0) {throw new IllegalArgumentException("a ==>" + a);
        }
        log.info("[" + counter.incrementAndGet() + "]Port:" + port + ", Execute at:" + new Date());
        return a * b * 20;
    }

    @OnSuccess("calc")
    public void onSuccess(Object result, MethodInvocation invocation) {log.info("Result:" + result + ", Take:" + (System.currentTimeMillis() - invocation.getTimestamp()));
    }

    @OnFailure("calc")
    public void onFailure(ThrowableProxy info, MethodInvocation invocation) {log.info("========================================");
        log.error("{}", info);
    }

阐明:

  1. 注解 @MultiProcessing 润饰办法 calc, 示意这个办法是多过程调用的
  2. onSuccess 和 onFailure 两个办法都是异步的调用的

办法分片

办法分片又叫办法并行处理,其实就是将一组参数的每一个参数应用过程池散发到不同利用上运行,而后再合并输入,并须要实现分片规定接口,见源码:

public interface Parallelization {Object[] slice(Object argument); // 切片

    Object merge(Object[] results);  // 合并

}

示例代码:

    @ParallelizingCall(value = "loop-test", usingParallelization = TestCallParallelization.class)
    public long total(String arg) {// 0,1,2,3,4,5,6,7,8,9
        return 0L;
    }

    public static class TestCallParallelization implements Parallelization {

        @Override
        public Long[] slice(Object argument) {String[] args = ((String) argument).split(",");
            Long[] longArray = new Long[args.length];
            int i = 0;
            for (String arg : args) {longArray[i++] = Long.parseLong(arg);
            }
            return longArray;
        }

        @Override
        public Long merge(Object[] results) {
            long total = 0;
            for (Object o : results) {total += ((Long) o).longValue();}
            return total;
        }

    }

阐明:

  1. 注解 @ParallelizingCall 润饰 total 办法,示意这个办法要做分片解决
  2. 参数 arg, 比如说你能够传 0,1,2,3,4,5,6,7,8,9,分片规定会调用 slice 办法将参数以“,”宰割,变成数组,而后将每个值转换成 long 型,再散发到各个利用执行,全副执行完了,再执行 merge 办法进行加和操作,有点 MapReduce 的滋味
  3. total 办法返回的 0,是指当参数为空或办法异样返回的默认值

微服务能力

Rest 客户端

示例代码:

@RestClient(provider = "test-service")
// @RestClient(provider = "http://192.168.159.1:5050")
public interface TestRestClient {@PostMapping("/metrics/sequence/{dataType}")
    Map<String, Object> sequence(@PathVariable("dataType") String dataType, @RequestBody SequenceRequest sequenceRequest);

}

阐明:

  1. 注解 @RestClient 润饰的接口阐明这是个 Http 客户端
  2. 注解中,provider 属性示意服务提供方,能够是集群中的某个利用名(${spring.application.name}), 也能够是具体 http 地址
  3. 反对 Spring 注解(GetMapping, PostMapping, PutMapping, DeleteMapping), 此外,用注解 @Api 可提供更细粒度的参数设置

网关

@EnableGateway
@SpringBootApplication
@ComponentScan
public class GatewayMain {public static void main(String[] args) {
        final int port = 9000;
        System.setProperty("server.port", String.valueOf(port));
        SpringApplication.run(GatewayMain.class, args);
    }
}

援用注解 @EnableGateway 就行了,tridenter 的网关底层是用 Netty4 实现的

配置路由:
@Primary
@Component
public class MyRouterCustomizer extends DefaultRouterCustomizer {

    @Override
    public void customize(RouterManager rm) {super.customize(rm);
        rm.route("/my/**").provider("tester5");
        rm.route("/test/baidu").url("https://www.baidu.com").resourceType(ResourceType.REDIRECT);
        rm.route("/test/stream").url("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png").resourceType(ResourceType.STREAM);
    }

}

阐明:
ResourceType 的 4 种类型:
DEFAULT, 转发申请
REDIRECT, 跳转
STREAM, 二进制流
FILE 保留文件

限流降级

限流是指在客户端限流,而非服务端
限流会依赖 3 个指标:

  1. 响应超时率
  2. 错误率
  3. 并发度
    默认状况,当这三个指标中有任一指标超过 80%,即会触发限流,调用降级服务
    限流指标统计类 : RequestStatisticIndicator
    降级服务接口:FallbackProvider
    相干源码可自行钻研

衰弱监控

目前 tridenter 提供了 3 个 HealthIndicator 的子类

  1. ApplicationClusterHealthIndicator
    显示集群的整体健康状态
  2. TaskExecutorHealthIndicator
    显示集群线程池的衰弱状态
  3. RestClientHealthIndicator
    显示 Rest 客户端的衰弱状态(响应超时率,错误率,并发度)

最初,微服务分布式合作框架 tridenter 的源码地址:https://github.com/paganini20…

退出移动版