随笔分类 - 并发编程
摘要:接上篇秒杀系统优化方案(上)吐血整理 3. 深入优化设计 3.1 初始方案问题分析 在前面针对数据库的优化中,由于数据库行级锁存在竞争造成大量的串行阻塞,我们使用了存储过程(或者触发器)等技术绑定操作,整个事务在MySQL端完成,把整个热点执行放在一个过程当中一次性完成,可以屏蔽掉网络延迟时间,减少
阅读全文
摘要:前一段时间好好研究了秒杀的问题,我把里面的问题好好总结了,可以说是比较全面的了,真的是吐血整理了。 由于我先是在word中整理的,格式都整理得比较好,放到博客上格式挺难调,暂时按word的格式来吧,有时间了在好好排版下。 主要需要解决的问题有两个: 优化的思路: 1) 尽量将请求拦截在系统上游 2)
阅读全文
摘要:在分布式架构或微服务架构下,必须保证一个应用服务器上保存Session后,其它应用服务器可以同步或共享这个Session,可能会出现在A1系统登录后创建并保存Session,再次发起请求,请求被转发到A2系统上显示未登录的情况。以下是几种常见的分布式session管理方案: 1.Session复制
阅读全文
摘要:缓存设计的误区 我们通常是这样设计的,应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。 那试想一下,如果取出来的null,需不需要放入cache呢?答案当然是需要的。 我们试想一下如果取出为null不放入cache会有什么结果?很显然每次取cache没有走db返回nu
阅读全文
摘要:下面是我对java并发编程与高并发解决方案的学习总结: 1、并发编程的基础 2、线程安全—可见性和有序性 3、线程安全—原子性 4、安全发布对象—单例模式 5、不可变对象 6、线程封闭 7、线程不安全类 8、同步容器 9、J.U.C之AQS 10、线程的几种创建方式 11、FutureTask、Fo
阅读全文
摘要:cpu多级缓存是计算机底层的东西,面试比较少问道。 java内存模型更加重要。相当于java这门语言相对于计算机底层定义了一个上层的模型,代码执行的操作是基于这个模型。 面试时比如问你对java内存模型的理解。 线程安全性这一章考点特别多,应该足够重视。 TreadLocal常问。并发容器更加重要些
阅读全文
摘要:简谈从零开始搭建一套业务相关监控报警系统 高可用原则:
阅读全文
摘要:切库的基础和实际运用—读写分离: 如何方便进行读写分离,目前有两种方式: 1.动态数据源切换 它是指程序运行时,把数据源动态的织入到程序中,让指定的程序连接主库还是从库 自定义注解完成数据库切库 2.直接定义查数据源和写数据源 直接在项目里定义两个数据库连接,一个是主库连接一个是从库连接,更新数据的
阅读全文
摘要:服务降级: 服务压力剧增的时候根据当前的业务情况及流量对一些服务和页面有策略的降级,以此环节服务器的压力,以保证核心任务的进行。 同时保证部分甚至大部分任务客户能得到正确的相应。也就是当前的请求处理不了了或者出错了,给一个默认的返回。 服务熔断:在股票市场,熔断这个词大家都不陌生,是指当股指波幅达到
阅读全文
摘要:限流就是通过对并发访问/请求进行限速或一个时间窗口内的请求进行限速,从而达到保护系统的目的。一般系统可以通过压测来预估能处理的峰值,一旦达到设定的峰值阀值,则可以拒绝服务(定向错误页或告知资源没有了)、排队或等待(例如:秒杀、评论、下单)、降级(返回默认数据) 限流不能乱用,否则正常流量会出现一些奇
阅读全文
摘要:前面我们已经提到单个服务器再优化,它的处理能力都是有上限的,因此我们选择多扩容以及使用缓存和消息队列等对程序进行优化。 下面介绍另一种方法,随着项目需求完成越来越多,应用自然也会越来越大,架构师将一个应用整体拆分成多个应用。 拆分的原则: 1.业务优先,确定业务边界 2.循序渐进,边拆分边测试 3.
阅读全文
摘要:消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能,成为异步RPC的主要手段之一。 消息被处理的过程相当于流程A被处理。我们这里以一个实际的模型来讨论下,比如用户下单成功时给用户发短信,如果没有这个消息队列,我们会选择同步调用发短信的接
阅读全文
摘要:应用需要支撑大量并发量,但数据库的性能有限,所以使用缓存来减少数据库压力与提高访问性能。 、 缓存的使用可以出现在1到4的各个环节中,每个环节的方案他们都各有特点。 特征 命中率 = 命中数 / (命中数 + 没有命中数) 最大空间:缓存最大空间一旦缓存中元素数量超过这个值(或者缓存数据所占空间超过
阅读全文
摘要:什么是扩容, 什么时候要扩容? 了解Java 内存结构的伙伴应该都知道 , 每个线程都有自己的工作内存, 占用内存大小取决于工作内存里变量的多少与大小 , 单个线程占用内存通常不会很大, 但是随着并发的线程不断的增加 , 从成百上千, 甚至几十万 , 占用的内存就会越来越多.这时候可能就要考虑给系统
阅读全文
摘要:(1)HashMap的线程不安全原因一:死循环 原因在于HashMap在多线程情况下,执行resize()进行扩容时容易造成死循环。 扩容思路为它要创建一个大小为原来两倍的数组,保证新的容量仍为2的N次方,从而保证上述寻址方式仍然适用。扩容后将原来的数组从新插入到新的数组中。这个过程称为reHash
阅读全文
摘要:Spring作为一个IOC/DI容器,帮助我们管理了许许多多的“bean”。但其实,Spring并没有保证这些对象的线程安全,需要由开发者自己编写解决线程安全问题的代码。Spring对每个bean提供了一个scope属性来表示该bean的作用域。它是bean的生命周期。例如,一个scope为sing
阅读全文
摘要:1. 使用本地变量 应该总是使用本地变量,而不是创建一个类或实例变量,通常情况下,开发人员使用对象实例作为变量可以节省内存并可以重用,因为他们认为每次在方法中创建本地变量会消耗很多内存。 2.使用不可变类 不可变类比如String Integer等一旦创建,不再改变,不可变类可以降低代码中需要的同步
阅读全文
摘要:什么是死锁? 通俗的说,死锁就是两个或者多个线程,相互占用对方需要的资源,而都不进行释放,导致彼此之间都相互等待对方释放资源,产生了无限制等待的现象。死锁一旦发生,如果没有外力介入,这种等待将永远存在,从而对程序产生严重影响。 死锁产生的必要条件 互斥条件:进程对锁分配的资源进行排他性使用 请求和保
阅读全文
摘要:继承Thread的弊端 1.每次new Thread的时候都需要新建一个线程,性能差 2.线程缺乏统一管理,可能无限制的新建线程,相互竞争,有可能占用过多系统资源导致死机或者OOM 3.Thread类缺少更多功能,比如更多的执行、定期执行、线程中断。 线程池的好处 1.重用存在的线程,减少对象创建、
阅读全文
摘要:我们之前学习创建线程有Thread和Runnable两种方式,但是两种方式都无法获得执行的结果。 而Callable和Future在任务完成后得到结果。 Future是一个接口,表示一个任务的周期,并提供了相应的方法来判断是否已经完成,以及获取任务的结果和取消任务。 FutureTask可用于异步获
阅读全文