业务中台(一)——总体介绍

一、总体介绍

随着公司不断的业务探索和实践,中台逐步完成了多项通用业务的沉淀,为后续项目的快速迭代,提供了有力的保障。

二、中台能力

在这里插入图片描述

三、设计实现

在这里插入图片描述

1、代理层

  • 配置加载:加载配置中心对应的应用配置信息
  • 访问控制:
    • 请求合法校验(参数、应用、权限、黑名单)
    • 流量控制
  • 监控告警:
    • dubbo线程池状态监控
    • 请求质量监控(请求量、响应时长、响应异常)

配置中心

通过配置中心,完成应用接入,对后续服务层和数据层提供访问控制。

技术栈
名称作用说明
mongo存储配置信息json数据方便配置信息扩展
redis配置信息缓存提高查询效率
caffeine配置信息本地缓存提高查询效率,降低数据库访问频率
threadlocal线程内配置信息共享解耦配置信息获取处理逻辑,方便服务层和数据层使用

2、数据层

统一封装了不同应用获取数据源操作,包括mongdb、redis、mysql、elasticsearch,支持了以下特性:

a、横向扩展

为了保证中台数据层的高可用性,对不同应用之间数据源进行了横向扩展隔离,避免了不同应用之间的互相影响,也方便了各自数据的维护。同时,也支持不同应用之间公用库,节约成本。

b、动态注册

通过数据源管理中心,动态管理数据源。添加修改前,主动检查配置信息的正确性。

c、懒加载

启动时不主动加载数据源,当有数据源操作时在加载,避免无用数据源创建。

d、热更新

通过redis发布订阅,实时监听数据源变更,自动完成数据源卸载,再次使用时通过懒加载策略加载最新数据源信息。

// 数据源缓存
private static volatile Map<String, Map<String, Object>> MAP = Maps.newHashMap();

/**
 * 缓存获取数据源
 **/
public <T, R> R getFromCache(DatabaseContext databaseContext, Class<T> tClass, Class<R> rClass, Function<T, R> function) {
    String connectName = databaseContext.getConnectName();
    Map<String, Object> beanMap = MAP.get(connectName);
    String cacheName = databaseContext.getApp() + rClass.getName();
    if (MapUtils.isNotEmpty(beanMap) && beanMap.containsKey(cacheName)) {
        return (R) beanMap.get(cacheName);
    }
    // 双检锁缓存查询
    synchronized (this) {
        beanMap = MAP.get(connectName);
        if (MapUtils.isNotEmpty(beanMap) && beanMap.containsKey(cacheName)) {
            return (R) beanMap.get(cacheName);
        }
        if (beanMap == null) {
            beanMap = Maps.newHashMap();
        }
        // spring容器获取数据源
        R result = function.apply(getConnectClient(databaseContext, tClass));
        beanMap.put(cacheName, result);
        MAP.put(connectName, beanMap);
        return result;
    }
}

/**
 * spring容器获取数据源
 **/
public <T> T getConnectClient(DatabaseContext databaseContext, Class<T> tClass) {
        ApplicationContext context = ApplicationContextHolder.getContext();
    String connectName = databaseContext.getConnectName();
    ConnectionTypeEnum type;
    if (tClass == SuishenRedisTemplate.class) {
        type = ConnectionTypeEnum.REDIS;
        connectName += "RedisTemplate";
    } else if (tClass == DomainDaoSupport.class) {
        type = ConnectionTypeEnum.MYSQL;
        connectName += "DomainDaoSupport";
    } else if (tClass == MongoTemplate.class) {
        type = ConnectionTypeEnum.MONGO;
        connectName += "MongoTemplate";
    } else if (tClass == ElasticsearchTemplate.class) {
        type = ConnectionTypeEnum.ELASTICSEARCH;
        connectName += "ElasticsearchTemplate";
    } else {
        throw new BusinessException("类型不支持!");
    }
	
    if (context.containsBean(connectName)) {
        return (T) ApplicationContextHolder.getBean(connectName);
    }
    // 数据中心查询数据源
     CustomDatabase config = customDatabaseDao.getDatabase(databaseContext.getProject(), databaseContext.getModel(), type);
     if (Objects.isNull(config)) {
         throw new BusinessException(connectName + "不存在!");
     }
     DefaultListableBeanFactory autowireCapableBeanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();
     AbstractConnectionBuilder builder = ConnectionBuildFactory.getBuilder(type);
     // spring容器加载数据源
     builder.build(config.convert(), autowireCapableBeanFactory);
     return (T) ApplicationContextHolder.getBean(connectName);
}

五、高可用性

  • 基于eone容器化的快速部署、动态扩容;
  • 多级缓存策略;
  • 基于cat、睿象云、钉钉的实时监控告警策略;
  • 数据源隔离,支持快速切换;
  • 基于dubbo的限流、熔断、服务降级策略。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值