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.Final2021-06-05 18:20:11 [INFO ] org.xnio - XNIO version 3.3.8.Final2021-06-05 18:20:11 [INFO ] org.xnio.nio - XNIO NIO Implementation Version 3.3.8.Final2021-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/12021-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 ApplicationRegistryCenter2021-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/12021-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@ComponentScanpublic 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@Componentpublic 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...