java-route
java-route copied to clipboard
Java technology route
红包架构 1.预资源下载 这些页面需要用到图片,视频或H5页面等资源。在活动期间,参与用户多,对资源的请求量很大,如果都通过实时在线访问,服务器的网络带宽会面临巨大压力,基本无法支撑;另外,资源的尺寸比较大,下载到手机需要较长时间,用户体验也会很差。因此,我们采用预先下载的方式, 在活动开始前几天把资源推送给客户端,客户端在需要使用时直接从本地 加载。 2.摇/拆红包 除夕的摇一摇子系统是专门为活动定制的,按时间轴进行各项活动,这里边最重要、同时也是请求量最大的是摇红包。从需求上看,系统需要完成两个事:用户可以通过摇一摇抢到红包,红包金额可以入到用户的支付账户。在除夕,系统需要在很短时间内将几十亿个红包发放下去,对性能和可用性要求很高。考虑到涉及资金的业务逻辑比较复杂,还有很多数据库事务处理,耗时会比较长,于是我们将抢红包(信息流)和红包的账务逻辑(业务流和资金流)异步化。将前一部分处理流程尽可能设计得轻量,让用户可以很快抢到红包,然后再异步完成剩下的账务逻辑。 1. 零 RPC 调用 在微信后台系统中,一般情况下客户端发起的请求都是通过接入服务 转发给具体的业务服务处理的,会产生 RPC 调用。但对于摇一摇请求,我 们将摇一摇逻辑直接嵌入接入服务中,接入服务可以直接处理摇一摇请求, 派发红包。 1. 零数据库存储 按一般的系统实现,用户看到的红包在系统中是数据库中的数据记录, 抢红包就是找出可用的红包记录,将该记录标识为属于某个用户。在这种 实现里,数据库是系统的瓶颈和主要成本开销。我们在这一过程完全不使 用数据库,可以达到几个数量级的性能提升,同时可靠性有了更好的保障。 支付系统将所有需要下发的红包生成红包票据文件 ; 一).将红包票据文件拆分后放到每一个接入服务实例中; 二).接收到客户端发起摇一摇请求后,接入服务里的摇一摇逻辑拿出一个红包票据,在本地生成一个跟用户绑定的加密票据,下发给客户端; 三).客户端拿加密票据到后台拆红包,后台的红包简化服务通过本地计算即可验证红包,完成抢红包过程。 3.异步化 用户抢到红包后不会同步进行后续的账务处理,请求会被放入红包异步队列,再通过异步队列转给微信支付后台,由微信支付后台完成后续业务逻辑。...
http://cailin.iteye.com/blog/2014486/ http://search.jikexueyuan.com/course?q=zookeeper http://www.open-open.com/lib/view/open1420599598828.html
http://www.cnblogs.com/dolphin0520/p/3784171.html
http://www.importnew.com/12607.html
http://blog.csdn.net/chjttony/article/details/6538452
http://ydlmlh.iteye.com/blog/1413573 http://it.deepinmind.com/java/2014/03/31/hashcode-method-performance-tuning.html http://www.cnblogs.com/nktblog/articles/2518111.html
在多线程程序设计中,经常会遇到一个线程等待一个或多个线程的场景,遇到这样的场景应该如何解决? 如果是一个线程等待一个线程,则可以通过await()和notify()来实现; 如果是一个线程等待多个线程,则就可以使用CountDownLatch和CyclicBarrier来实现比较好的控制。 下面来详细描述下CountDownLatch的应用场景: 例如:百米赛跑:8名运动员同时起跑,由于速度的快慢,肯定有会出现先到终点和晚到终点的情况,而终点有个统计成绩的仪器,当所有选手到达终点时,它会统计所有人的成绩并进行排序,然后把结果发送到汇报成绩的系统。 其实这就是一个CountDownLatch的应用场景:一个线程或多个线程等待其他线程运行达到某一目标后进行自己的下一步工作,而被等待的“其他线程”达到这个目标后继续自己下面的任务。 这个场景中: 1. 被等待的“其他线程”------>8名运动员 2. 等待“其他线程”的这个线程------>终点统计成绩的仪器 那么,如何来通过CountDownLatch来实现上述场景的线程控制和调度呢? jdk中CountDownLatch类有一个常用的构造方法:CountDownLatch(int count); ``` 两个常用的方法:await()和countdown() ``` 其 中count是一个计数器中的初始化数字,比如初始化的数字是2,当一个线程里调用了countdown(),则这个计数器就减一,当线程调用了 await(),则这个线程就等待这个计数器变为0,当这个计数器变为0时,这个线程继续自己下面的工作。下面是上述CountDownLatch场景的 实现: Work类(运动员): ` import java.util.concurrent.CountDownLatch; public class Work implements Runnable...
正如每个Java文档所描述的那样,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。在Java并发中,countdownlatch的概念是一个常见的面试题,所以一定要确保你很好的理解了它。在这篇文章中,我将会涉及到在Java并发编 程中跟CountDownLatch相关的以下几点: 目录 CountDownLatch是什么? CountDownLatch如何工作? 在实时系统中的应用场景 应用范例 常见的面试题 CountDownLatch是什么 CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。 CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。 CountDownLatch的伪代码如下所示: //Main thread start //Create CountDownLatch for N threads //Create and start N threads //Main thread wait on latch...
Quorom 机制,是一种分布式系统中常用的,用来保证数据冗余和最终一致性的投票算法,其主要数学思想来源于鸽巢原理。 在有冗余数据的分布式存储系统当中,冗余数据对象会在不同的机器之间存放多份拷贝。但是同一时刻一个数据对象的多份拷贝只能用于读或者用于写。 该算法可以保证同一份数据对象的多份拷贝不会被超过两个访问对象读写。 算法来源于[Gifford, 1979][3][1]。 分布式系统中的每一份数据拷贝对象都被赋予一票。每一个操作必须要获得最小的读票数(Vr)或者最小的写票数(Vw)才能读或者写。如果一个系统有V票(意味着一个数据对象有V份冗余拷贝),那么这最小读写票必须满足: Vr + Vw > V Vw > V/2 第一条规则保证了一个数据不会被同时读写。当一个写操作请求过来的时候,它必须要获得Vw个冗余拷贝的许可。而剩下的数量是V-Vw 不够Vr,因此不能再有读请求过来了。同理,当读请求已经获得了Vr个冗余拷贝的许可时,写请求就无法获得许可了。 第二条规则保证了数据的串行化修改。一份数据的冗余拷贝不可能同时被两个写请求修改。 算法的好处 在分布式系统中,冗余数据是保证可靠性的手段,因此冗余数据的一致性维护就非常重要。一般而言,一个写操作必须要对所有的冗余数据都更新完成了,才能称为成功结束。比如一份数据在5台设备上有冗余,因为不知道读数据会落在哪一台设备上,那么一次写操作,必须5台设备都更新完成,写操作才能返回。 对于写操作比较频繁的系统,这个操作的瓶颈非常大。Quorum算法可以让写操作只要写完3台就返回。剩下的由系统内部缓慢同步完成。而读操作,则需要也至少读3台,才能保证至少可以读到一个最新的数据。 Quorum的读写最小票数可以用来做为系统在读、写性能方面的一个可调节参数。写票数Vw越大,则读票数Vr越小,这时候系统写的开销就大。反之则写的开销就小。
续前篇[《Redis Sentinel机制与用法(一)》](https://github.com/edagarli/java-route/issues/8) 概述 Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自懂切换。 它的主要功能有以下几点 不时地监控redis是否按照预期良好地运行; 如果发现某个redis节点运行出现状况,能够通知另外一个进程(例如它的客户端); 能够进行自动切换。当一个master节点不可用时,能够选举出master的多个slave(如果有超过一个slave的话)中的一个来作为新的master,其它的slave节点会将它所追随的master的地址改为被提升为master的slave的新地址。 无failover时的配置纠正 即使当前没有failover正在进行,sentinel依然会使用当前配置去设置监控的master。特别是: 根据最新配置确认为slaves的节点却声称自己是master(参考上文例子中被网络隔离后的的redis3),这时它们会被重新配置为当前master的slave。 如果slaves连接了一个错误的master,将会被改正过来,连接到正确的master。 Slave选举与优先级 当一个sentinel准备好了要进行failover,并且收到了其他sentinel的授权,那么就需要选举出一个合适的slave来做为新的master。 slave的选举主要会评估slave的以下几个方面: 与master断开连接的次数 Slave的优先级 数据复制的下标(用来评估slave当前拥有多少master的数据) 进程ID 如果一个slave与master失去联系超过10次,并且每次都超过了配置的最大失联时间(down-after-milliseconds option),并且,如果sentinel在进行failover时发现slave失联,那么这个slave就会被sentinel认为不适合用来做新master的。 更严格的定义是,如果一个slave持续断开连接的时间超过 (down-after-milliseconds \* 10) + milliseconds_since_master_is_in_SDOWN_state 就会被认为失去选举资格。 符合上述条件的slave才会被列入master候选人列表,并根据以下顺序来进行排序: sentinel首先会根据slaves的优先级来进行排序,优先级越小排名越靠前(?)。...