月度归档: 2018 年 5 月

  • 使用Gradle构建缓存服务加速构建

    使用Gradle构建缓存服务加速构建

    有时候会在本地使用docker-compose,如果compose中没有image文件这些还好,如果有那就要设计到构建了,因为构建的时候都是在镜像中,所以相对的速度比较慢,没法重复构建缓存。有时候即便不在docker环境中还是想重用缓存来加速。

    Gradle官方就提供了一个这样的服务, build-cache-node,这个服务本来是为了企业版服务的,但是非企业版也可以部分使用。因为提供了docker镜像,直接启动就行了。

    docker run gradle/build-cache-node

    在项目配置中需要添加Cache Server地址,比如

    buildCache {
        remote(HttpBuildCache) {
            url = 'http://gradle-cache-server/'
            push = true
        }
    }

    然后在构建中加上–build-cache就行了。

    如果需要认证也可以自己修改配置。

    参考:

    https://hub.docker.com/r/gradle/build-cache-node/…

  • 基于Zookeeper的分布式锁

    ZooKeeper是Apache软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。 ZooKeeper曾经是Hadoop的一个子项目,但现在是一个独立的顶级项目。

    在Zookeeper中,znode是一个跟Unix文件系统路径相似的节点,可以往这个节点存储或获取数据。节点的类型又分为临时节点和永久节点,又可以带有序号。锁的本质是资源的占有,那么就需要有一个对象,在ZooKeeper中就可以是它的znode。所以最直接的锁思路就是占有一个znode。步骤如下:

    1. lock方法调用时尝试创建一个临时节点
    2. 如果节点创建成功,那么即获得锁
    3. 创建节点失败的就需要等待(等待可以是固定等待时间或者是使用Watch机制)
    4. 获得锁的线程释放锁时断开和ZooKeeper的链接即可

    这个方法的问题在于等待,如果采用Watch机制,那么就容易出现大量订阅。

    更常见的一种方法是将操作集中在一个目录中,比如/locker/user/。

    在该目录下创建临时有序节点,那么没有获得锁的线程其实是可以感知其他线程的,比如最小序列是000001,而当前线程的序号是000010。大致方法如下:

    1. lock方法调用时创建临时有序节点
    2. 判断当前目录下的最小节点是否是自己持有的,如果持有就获得锁
    3. 如果最小节点不是自己获得的,那么就需要等待,可以watch最小节点的删除事件,而不是目录的情况
    4. 释放锁时断开链接即可

    当然原理比较容易理解,但是实际使用中可以直接用封装好的,比如curator-recipes中的InterProcessMutex,InterProcessReadWriteLock等。

    参考资料:

    https://zookeeper.apache.org/doc/r3.1.2/recipes.html

    https://www.jianshu.com/p/5d12a01018e1

     

     …

  • 分布式环境下事务一致性

    在当今流行微服务体系结构中,一个看似简单的功能可能需要调用多个服务,并操作多个数据库。比如创建用户操作,首先需要在服务A创建用户的帐号,在服务B中创建对应的积分记录,然后服务C中添加用户优惠信息等,由于网络,服务自身的可用性等,这几个操作中的一个或者多个可能会失败,为了保持事物一致性,就必须有对应的手段或者技术。

    实现分布式环境下的事务一致性保证有以下几种方式:

    1. 两阶段提交协议
    2. 三阶段提交协议
    3. TCC 协议
    4. 基于可靠消息投递方案
    5. 基于补偿模式方案

    两阶段提交包括准备阶段和提交阶段,主要需要事务协调者TM和资源管理器RM参与。首先在准备阶段,首先 TM 发送指令到 RM,RM 对自身状态进行充分评估,如果 RM 经过评估认为操作能够完成, 那么锁定资源但是不提交。在提交阶段,如果每个RM都反馈成功准备的信息, 再进入第二步执行确认操作,即资源预留及操作均成功,TM发送RM提交操作的指令, RM如果没有成功,则需要执行逆操作来取消第一步操作的影响。

    两阶段提交协议的主要问题在于虽然一致性很强,但是锁太重,如果TM出现故障,会出现阻塞。

    三阶段提交协议从字面看就是对两阶段的补充,引入了超时机制,将准备阶段拆分为询问和预提交两个部分。询问时RM只响应是或者否,不锁定资源,超时就直接终止。预提交的时候RM再记录日志和执行锁。

    很明显,三阶段虽然多了一个步骤,但是实际上只是提交发现无法执行的情况,之后并没有特别的改进。

    TCC 协议会将一个任务拆分成三个环节:尝试(Try ) 、 确认(Confirm ) 、 取消(Cancel )。正常的流程是第一步先执行尝试操作,如果不成功,就执行逆操作取消第一步的影响。它和两阶段的区别在于RM需要具备一定的自动修复能力,如果RM中任何一个失败,就要求所有RM执行第一步的逆操作。Restful情况下的设计有一篇论文比较详细《Atomic Distributed Transactions: a RESTful Design》,公开下载的可以看看。

    基于可靠消息投递方案相对比较简单,对于可以异步处理的事务,采用消息队列来处理,只要保证了幂等性(确保消息任意多次执行所产生的影响均与一次执行的影响相同)那么就可以重复重试即可。

    基于补偿模式方案对应更业务一些。在目前所知的情况下,一旦有操作出现了不正常的情况,我们需要及时的去修复系统中有问题的子操作。这些操作最终的目的都是让系统的各个部分达到最终的一致性。

    这里网上找到了可靠消息投递方案和TCC的示意图,可以参考一下:

    参考链接:

    https://segmentfault.com/q/1010000000304596…

  • 阿里云大学认证

    之前阿里云搞活动,顺手买了阿里巴巴编码规范(Java)认证。https://edu.aliyun.com/course/417

    今天下午仔细看了一遍,其实内容就是之前免费下载的PDF,而且版本还不是最新的,认证学习里面的版本是1.3.0,点击下载过去下的是1.3.1。

    认证的时候需要开启摄像头,验证身份证,感觉还蛮正式的,唯一体验不好的就是摄像头会定时抓拍,经常头动一下,或者摄像头位置没对,就会弹窗警告。。。

    最后的证书看着还比较正式,还有过期时间。总的来说我觉得如果自己能认真看资料,那下载PDF就行了,如果需要点动力,可以考虑花钱买认证。

    …