实现微服务

变通实现微服务的per request以提高IO效率

效率

同一次业务操作过程中,往往会出现某种操作被重复执行,逻辑上来讲如果只执行一次是最理想的。这里所指的操作特指一些IO操作,比如从数据库中获取登录人的信息,也就是说如果一次请求中包含5个小逻辑,这5个小逻辑包含3次获取用户信息的操作,理想的情况是3次只有一次是从数据库中加载,其余的两次从缓存中获取。

  • 多次调用,每个服务实现独自请求用户信息。

  • 一次调用,多次读取。首先从Context中加载,如果失败从数据库中加载,最后将结果存入Context。

前提

限于非web环境,这里是dubbo实现的微服务。如果是web环境的话解决问题比较简单,因为我们可以充分利用Spring Framwork中提到的三个bean生命周期的特殊来解决:

  • request
  • session
  • global

案例

将老的价格数据迁移成新的价格数据,这里大概是如下的步骤:

  • 删除新老价格的关系,因为需要支持重复迁移
  • 禁用之前已经存在的价格规则,规则是描述价格在某种场景下生效的逻辑
  • 创建新的价格
  • 创建新的规则
  • 启用新规则

上面步骤的价格,规则,关系数据分别属于三个业务对象,自身都具备CRUD的服务接口,这些CRUD都需要记录操作人信息,记录的标准就是接口传入的操作人所持有的token,我们需要将这个token转换成userId,userName之类的信息与价格,规则等信息一并存储。

时序图如下:

问题:迁移一条价格多次读取用户信息效率低

由于迁移价格会涉及到多个对象的操作,而操作这些具体业务对象的接口并不支持传具体的userId,userName只支持token,所以不可避免的会在保存价格等信息时各自去根据token查询操作人信息。实测一个价格完成一次数据迁移涉及到获取用户信息的次数多达20+次,效率是比较低,如何去解决呢?

现状

由于我目前实现的微服务是无状态的,也不是web环境,所以上面提到的那些bean的作用域功能就使用不上。

目标

实现类似request作用域的功能,一次请求仅执行一次,其余的请求从缓存中获取结果以提高IO操作效率。

方案

可采用TreadLocal来当缓存,存储频繁读取的数据。增加了CacheContext,获取用户首先从CacheContext中取,如果为空则从数据库加载然后回写到Treadlocal中,下一次再请求用户信息时就可以命中缓存不需要再次从数据库中加载,显然效率得到了质的提升。

时序图如下:

实现步骤如下:

  • 创建Context数据对象
    缓存的容器为TreadLocal,可以定义多个需要缓存的属性,并提供一个清除所有缓存的方法。清除的方法是必做的,否则会一直停留在线程中,当线程被再次利用时会获取到上一次请求存储的数据。
@Service
public class ProductContext {

    private static Logger logger = Logger.getLogger(CiaServiceImpl.class);
    private ThreadLocal<CiaUserInfo> ciaUserInfoThreadLocal=new ThreadLocal<>();
    private void clearCiaUserInfo(){
        this.ciaUserInfoThreadLocal.remove();
        this.logger.info("清除getTokenInfo缓存成功");
    }

    public void setCiaUserInfoToCache(CiaUserInfo ciaUserInfo){
        this.clearCiaUserInfo();
        this.ciaUserInfoThreadLocal.set(ciaUserInfo);
        this.logger.info("将getTokenInfo存储到缓存中");
    }

    public CiaUserInfo getCiaUserInfoFromCache(String token){
        CiaUserInfo ciaUserInfo =this.ciaUserInfoThreadLocal.get();
        if(null!=ciaUserInfo){
            this.logger.info("从缓存中获取到用户信息getTokenInfo");
        }
        return ciaUserInfo;
    }

    public void clearAll(){
        this.clearCiaUserInfo();
        this.logger.info("清除ProductContext的缓存成功");
    }

}
  • 修改获取用户信息的服务类,结合Context操作缓存。
public CiaUserInfo getTokenInfo(String token) throws Exception {

        CiaUserInfo result = this.productContext.getCiaUserInfoFromCache(token);
        if(null!=result){
            return result;
        }
        else {
            result=new CiaUserInfo();
        }

        //...get user from db
        this.productContext.setCiaUserInfoToCache(result);
        return result;
    }
  • 增加注解,用来标识哪些方法是需要使用缓存的
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LocalCacheContext {

    /**
     * 是否启动
     * @return
     */
    boolean enable() default true;

}
  • 增加拦截器
    TreadLocal中存入的信息需要有效及时的释放,配合上面申明的注解来完成。
@Aspect
public class LocalCacheContextInterceptor {

    private Logger logger = LoggerFactory.getLogger(getClass().getName());

    @Autowired
    private ProductContext productContext;

    @Pointcut("execution(* product.service.service.impl.*.*(..))")
    public void pointCut() {
    }

    @After("pointCut()")
    public void after(JoinPoint joinPoint) throws ProductServiceException {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method targetMethod = methodSignature.getMethod();

        LocalCacheContext localCacheContext= targetMethod.getAnnotation(LocalCacheContext.class);
        if(null!=localCacheContext){
            this.productContext.clearAll();
        }
    }

}
  • 客户端调用
    @LocalCacheContext
    public void migrationPrice(Long priceId) throws ProductServiceException {
        this.migrationPriceService.migrationPrice(priceId);
    }

标签: java性能优化

时间: 2024-08-06 02:11:48

实现微服务的相关文章

用友iuap云运维平台支持基于K8s的微服务架构

什么是微服务架构? 微服务(MicroServices)架构是当前互联网业界的一个技术热点,业内各公司也都纷纷开展微服务化体系建设.微服务架构的本质,是用一些功能比较明确.业务比较精练的服务去解决更大.更实际的问题.该架构强调的一些准则:单一职责.协议轻量.进程隔离.数据分离.独立部署.按需伸缩. 什么是Kubernetes? Kubernetes是Google开源的容器集群管理系统,其提供应用部署.维护. 扩展机制等功能,利用Kubernetes能方便地管理跨机器运行容器化的应用,其主要功能:

初识微服务

1.背景 在云场景下,突变已经成为一种常态. 突变包括3个情形: 1. 业务突变 2. 流量突变 3. 应用故障 微服务能够敏捷应对以上情形. 2. 什么是微服务 微服务是一种架构模式,而并不是架构本身.微服务提倡围绕业务构建服务,把单体应用拆分成功能单一的服务,每个服务运行在一个进程中,服务间通过轻量级机制(restful)进行通信.并且可以独立进行开发,部署,运维. 3. 微服务缺点 1)  分布式系统本身的复杂性: 数据一致性等 2) 进程内通信变成网络通信,性能有损耗

创建微服务?请先回答这10个问题

原文地址:http://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&mid=401654497&idx=1&sn=5cac9aa4ae113592e1513c1ff70ea917&scene=21#wechat_redirect 乍一看微服务似乎很容易构建,但是要真正构建微服务,要完成的工作可比在容器里运行一些代码,并在这些代码间使用HTTP请求进行通信,要多得多.在开发新的微服务之前--必须得在新服务部署到生产环境之前--你需要回答

使用Ratpack和Spring Boot打造高性能的JVM微服务应用

使用Ratpack和Spring Boot打造高性能的JVM微服务应用 这是我为InfoQ翻译的文章,原文地址:Build High Performance JVM Microservices with Ratpack & Spring Boot,InfoQ上的中文地址:使用Ratpack与Spring Boot构建高性能JVM微服务. 在微服务天堂中Ratpack和Spring Boot是天造地设的一对.它们都是以开发者为中心的运行于JVM之上的web框架,侧重于生产率.效率以及轻量级部署.他

微服务架构

互联网保险O2O平台微服务架构设计 关于架构,笔者认为并不是越复杂越好,而是相反,简单就是硬道理也提现在这里.这也是微服务能够流行的原因,看看市场上曾经出现的服务架构:EJB.SCA.Dubbo等等,都比微服务先进,都比微服务功能完善,但它们都没有微服务这么深入民心,就是因为他们过于复杂.简单就是高科技,苹果手机据说专门有个团队研究如何能让用户更加简单的操作.大公司都是由小公司发展起来的,如果小公司在开始技术选型时感觉某个框架费时费力就不会选择,而小公司发展到大公司的过程,一般也伴随着系统不断优

深解微服务架构:从过去,到未来|架构(2015-07-15)

随着用户需求个性化.产品生命周期变短,微服务架构是未来软件软件架构朝着灵活性.扩展性.伸缩性以及高可用性发展的必然方向.同时,以Docker为代表的容器虚拟化技术的盛行,将大大降低微服务实施的成本,为微服务落地以及大规模使用提供了坚实的基础和保障. 微服务的诞生   微服务架构(Microservice Architect)是一种架构模式,它提倡将单块架构的应用划分成一组小的服务,服务之间互相协调.互相配合,为用户提供最终价值.每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟

微服务 - 文章

[微服务与容器的监控 —— 来自Adrian Cockcroft的挑战][http://www.infoq.com/cn/news/2015/07/monitoring-microservices]Adrian Cockcroft在GlueCon 2015大会上为听众列举了如何对微服务与基于容器的应用进行监控的多条规则.他还重强调了在监控cloud native并且基于容器的系统时所面临的挑战,并介绍了微服务模拟与可视化工具“Spigo” [微服务的好处][http://www.infoq.co

孢子框架-接口访问层、ESB、微服务API GateWay对比

如果从百度去搜索“接口访问层”你会发现主要是.NET里面的技术,叫做IDAL,其实是数据访问层接口.它的主要作用是兼容多种数据库.比如你定义一个标准接口,然后实现改接口的SqlServer访问和Oracle访问,那么利用IDAL就可以自由切换数据库.看.NET DEMO PetShop4,总共有22个项目.大体思想是3层,从Model.DAL.BLL,然后他在各层上又采用了工厂模式,把逻辑与实现想分离,比如以前BLL直接调用DAL就好了,但现在BLL却调用了IDAL,IDAL就是一个接口层,里面

腾讯正式对外开源高性能 RPC 开发框架与微服务平台Tars

Tars 是将腾讯内部使用的微服务架构 TAF(Total Application Framework)多年的实践成果总结而成的开源项目,目前已于4月10日正式对外开源. 作为支持多语言的高性能 RPC 开发框架和配套一体化的服务治理平台,Tars可以帮助企业或者用户以微服务的方式快速构建稳定可靠的分布式应用,它的设计灵感来源于采取分层思想,实现开发与运营之间的分离.目前该框架在腾讯内部,已经在 160 多个业务(如手机浏览器.应用宝.手机管家.手机QQ.手机游戏等).1.6 多万台服务器上运行

基于Spring Cloud的微服务构建学习-3 服务治理-Spring Cloud Eureka之高可用注册中心

什么叫高可用 高可用一般指服务的冗余,一个服务挂了,可以自动切换到另一个服务上,不会影响到客户体验. 高可用注册中心 在微服务架构这样的分布式环境中,我们需要充分考虑发生故障的情况,所以在生产环境中必须对各个组件进行高可用部署,对于微服务如此,对于服务中心也一样. Eureka Server的设计一开始就考虑了高可用问题,在Eureka的服务治理设计中,所有节点既是服务提供方,也是服务消费方,服务注册中心也不例外.在前一篇随笔中用到过这样的配置: eureka.client.register-w