1. Hmily的性能问题?
答:Hmily是采用AOP切面的方式与你的RPC方法绑定,无非就是在你RPC调用的时候,保存了日志(通过异步disruptor),传递了一些参数。现在confrim,cancel也都为异步的调用,因此其性能与你的rpc性能一样。记住Hmily不生产事务,Hmily只是分布式事务的搬运工。之前Hmily在AOP切面加了一把锁,导致了性能下降。现在已经全部修复,并且全部异步化。
2. 关于RPC调用超时Hmily是怎么处理的?
答: 我们支持在分布式环境中调用一个RPC方法,如果超时了。比如dubbo设置的超时时间是100ms,可能你的方法用了140ms,但是你的方法是执行成功了的。但是对调用方来说,你是失败的。这个时候需要回滚。所以Hmily的做法是。调用者认为你是失败的,不会将加入的回滚调用链条中。因此超时的rpc接口方,进行自身的回滚。会有一个定时任务来进行回滚,因为日志状态是try阶段,会调用cancel方法进行回滚,从而到达最终一致性!
3. Hmily支持集群部署的问题?以及集群环境中,定时任务日志恢复的问题?
答:Hmily是和你的应用AOP切面绑定在一起的,天然支持集群。集群环境中定时恢复问题,其实几乎没有,除非你的集群同时一下挂掉,才会有这个问题。当你集群同时挂掉,在恢复的时候,日志会有一个version字段,更新成功的,才会去进行恢复。
4. Hmily是异步保存日志的,那么很极端情况下(代码刚好执行到这一行,然后jvm退出,断电啦什么的),日志还没保存那怎么处理呢?
答:在AOP切面中,会先进行日志的异步保存,注意状态是PRE_TRY。在try执行完成后,更新为try。就算存在断电,什么你在打断电调试,然后kill服务之类的。(Mysql我都可以让他事务失效,你信不信?)我只能说,不要花大力气去解决那些偶然的事情,最好的解决办法是不解决它。
5.Hmily针对高并发时候的参数配置调优。
可能这部门内容针对熟悉Hmily的人来说,不熟悉的也没关系。直接上github上看相关文档就好。
- hmily支持Spring bean xml 方式的配置,同时也支持spring boot start yml方式的配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
<span class="line"><span class="tag"><<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"hmilyTransactionBootstrap"</span> <span class="attr">class</span>=<span class="string">"com.hmily.tcc.core.bootstrap.HmilyTransactionBootstrap"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"serializer"</span> <span class="attr">value</span>=<span class="string">"kryo"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"recoverDelayTime"</span> <span class="attr">value</span>=<span class="string">"120"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"retryMax"</span> <span class="attr">value</span>=<span class="string">"3"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"loadFactor"</span> <span class="attr">value</span>=<span class="string">"2"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"scheduledDelay"</span> <span class="attr">value</span>=<span class="string">"120"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"scheduledThreadMax"</span> <span class="attr">value</span>=<span class="string">"4"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"bufferSize"</span> <span class="attr">value</span>=<span class="string">"4096"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"consumerThreads"</span> <span class="attr">value</span>=<span class="string">"32"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"started"</span> <span class="attr">value</span>=<span class="string">"false"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"asyncThreads"</span> <span class="attr">value</span>=<span class="string">"32"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"repositorySupport"</span> <span class="attr">value</span>=<span class="string">"db"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"tccDbConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"com.hmily.tcc.common.config.TccDbConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"url"</span></span></span> <span class="line"><span class="tag"> <span class="attr">value</span>=<span class="string">"jdbc:mysql://192.168.1.98:3306/tcc?useUnicode=true&characterEncoding=utf8"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"driverClassName"</span> <span class="attr">value</span>=<span class="string">"com.mysql.jdbc.Driver"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"username"</span> <span class="attr">value</span>=<span class="string">"root"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"password"</span> <span class="attr">value</span>=<span class="string">"123456"</span>/></span></span> <span class="line"> <span class="tag"></<span class="name">bean</span>></span></span> <span class="line"> <span class="tag"></<span class="name">property</span>></span></span> <span class="line"> <span class="tag"></<span class="name">bean</span>></span></span> |
|
serializer :这里我推荐使用是kroy。当然hmily也支持hessian,protostuff,jdk。在我们测试中表现为: kroy>hessian>protostuff>jdk
recoverDelayTime :定时任务延迟时间(单位是秒,默认120。这个参数只是要大于你的rpc调用的超时时间设置。
retryMax : 最大重复次数,默认3次。当你的服务down机,定时任务会执行retryMax次数去执行你的cancel还是confrim。
bufferSize: disruptor的bufferSize,当高并发的时候,可以调大。注意是 2n
consumerThreads distuptor消费线程数量,高并发的时候,可以调大。
started: 注意在是发起方的时候,把此属性设置为true。参与方为false。
asyncThreads 异步执行confirm和cancel线程池线程的大小,高并发的时候请调大
接下来是最重要的事务日志的存储 在我们的压测中,推荐使用mongo。表现为 mongodb>redis集群>mysql>zookeeper
6.如果你采用mongodb存储日志,配置如下(url可以配置成mongdb集群的url)
|
<span class="line"><span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"repositorySupport"</span> <span class="attr">value</span>=<span class="string">"mongodb"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"tccMongoConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"com.hmily.tcc.common.config.TccMongoConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"mongoDbUrl"</span> <span class="attr">value</span>=<span class="string">"192.168.1.68:27017"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"mongoDbName"</span> <span class="attr">value</span>=<span class="string">"happylife"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"mongoUserName"</span> <span class="attr">value</span>=<span class="string">"xiaoyu"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"mongoUserPwd"</span> <span class="attr">value</span>=<span class="string">"123456"</span>/></span></span> <span class="line"> <span class="tag"></<span class="name">bean</span>></span></span> <span class="line"> <span class="tag"></<span class="name">property</span>></span></span> |
|
7.如果你采用redis存储日志,配置如下:
- redis单节点
|
<span class="line"><span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"repositorySupport"</span> <span class="attr">value</span>=<span class="string">"redis"</span> /></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"tccRedisConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"com.hmily.tcc.common.config.TccRedisConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"hostName"</span></span></span> <span class="line"><span class="tag"> <span class="attr">value</span>=<span class="string">"192.168.1.68"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"port"</span> <span class="attr">value</span>=<span class="string">"6379"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"password"</span> <span class="attr">value</span>=<span class="string">""</span>/></span></span> <span class="line"> <span class="tag"></<span class="name">bean</span>></span></span> <span class="line"> <span class="tag"></<span class="name">property</span>></span></span> |
|
- redis哨兵模式集群:
|
<span class="line"><span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"repositorySupport"</span> <span class="attr">value</span>=<span class="string">"redis"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"tccRedisConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"com.hmily.tcc.common.config.TccRedisConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"masterName"</span> <span class="attr">value</span>=<span class="string">"aaa"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"sentinel"</span> <span class="attr">value</span>=<span class="string">"true"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"sentinelUrl"</span> <span class="attr">value</span>=<span class="string">"192.168.1.91:26379;192.168.1.92:26379;192.168.1.93:26379"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"password"</span> <span class="attr">value</span>=<span class="string">"123456"</span>/></span></span> <span class="line"> <span class="tag"></<span class="name">bean</span>></span></span> <span class="line"> <span class="tag"></<span class="name">property</span>></span></span> |
|
- redis集群:
|
<span class="line"><span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"repositorySupport"</span> <span class="attr">value</span>=<span class="string">"redis"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"tccRedisConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"com.hmily.tcc.common.config.TccRedisConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"cluster"</span> <span class="attr">value</span>=<span class="string">"true"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"clusterUrl"</span> <span class="attr">value</span>=<span class="string">"192.168.1.91:26379;192.168.1.92:26379;192.168.1.93:26379"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"password"</span> <span class="attr">value</span>=<span class="string">"123456"</span>/></span></span> <span class="line"> <span class="tag"></<span class="name">bean</span>></span></span> <span class="line"> <span class="tag"></<span class="name">property</span>></span></span> |
|
8.如果你采用zookeeper存储日志,配置如下:
|
<span class="line"><span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"repositorySupport"</span> <span class="attr">value</span>=<span class="string">"zookeeper"</span>/></span></span> <span class="line"><span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"tccZookeeperConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"om.hmily.tcc.common.config.TccZookeeperConfig"</span>></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"host"</span> <span class="attr">value</span>=<span class="string">"192.168.1.73:2181"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"sessionTimeOut"</span> <span class="attr">value</span>=<span class="string">"100000"</span>/></span></span> <span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"rootPath"</span> <span class="attr">value</span>=<span class="string">"/tcc"</span>/></span></span> <span class="line"> <span class="tag"></<span class="name">bean</span>></span></span> <span class="line"><span class="tag"></<span class="name">property</span>></span></span> |
|
小结
使用Hmily,一个注解,几行配置轻轻松松搞定高并发分布式事务!