一、高并发
高并发,这个网站处理高并发,它不是一招就解决的,它是一系列问题。第一打开浏览器,打开浏览器访问网站,浏览的人数越多,这个网站的性能就越低,这个是要跟web服务器要交互的,减少交互的内容量,是不是就可以解决这个高并发呀。
1.浏览器
在浏览器的这一层,尽可能的降低和程序的交互,而浏览器跟程序怎么降低交互,那就是静态化【jsp页面会先转成html格式的,不适合用于电商有些模块的开发】,网站打开,影响网站速度的,还有图片,并发量一大,图片加载就慢很多。所以呢,就是用独立的图片服务器。{图片怎么调用,很简单,就一个url地址,传一个file,阿里云就返回一个url地址(没听懂!)}.而且图片较多,图片一定得压缩,除了压缩,有的图片太大,还可以将图片切割,比如一个网站主页的轮播图,一个页面可能有10个img标签,这时候选择同步还是异步,同步就是第一张图不加载完,后面的图片没法加载;异步加载的图片互相不影响,第一张图片没加载出来,没关系,你不影响我,我第二张能加载出来。所以一张900kb的图片用于展示,加入一个网站的主页3秒钟没加载出来,这会造成客户的流失,所以呢,第一,网页静态化,第二尽可能的压缩图片,第三对图片进行切割,进行横向切割或者纵向切割,第四,网页进行了静态化,但是网站的主页,网站商品的价格跟数量是变化的,这个是动态的,这个时候,我们就可以用到缓存了。这是浏览器这方面,同时,同一页面的ajax加载的内容量不要太大,一个页面加载商品详情,我一个ajax查询了一个集合,将查询的结果集进行操作(html拼接),拼一个展示一个比全部加载效果好的多{局部加载比全部加载效果要好得多}。产生用户体验度会更高。(这是浏览器这方面能想到的问题)
2.后端代码
然后来到java这一层,我们一直在使用spring,因为spring能有效降低内存(为什么能降低内存?),ioc是保证所有的对象都是单例模式,提升java代码的复用性(封装),图片提取出去,不放在tomcat下,然后这个java代码使用分布式(什么是分布式?),java代码可以放在Apache+tomcat集群(这是什么?)或者这个nginx+tomcat集群(负载均衡)里面,这个时候也不是说在一台电脑上配了nginx+tomcat集群(那烂的跟狗屎似的),一个Apache或者一个nginx占了一台独立的服务器,tomcat配在其他电脑上,这时就有一个问题(一台电脑配一个tomcat好还是一个tomcat配是个tomcat好:即就是一台电脑配几个tomcat),一个tomcat占用一个进程,那么有没有可能一个tomcat造成4g内存溢出,这个就牵扯tomcat调优(tomcat优化),tomcat的内存容量和链接数是可以扩大的,tomcat内存只有512兆,默认的tomcat的访问量都能支持500k(这儿没听清),在一个服务器里面写一个死的for循环在list里面不断add数据,就会造成内存溢出,那么一台电脑配多少个tomcat好呢?一个有点少,这对CPU来说没发挥他的作用,一个cpu是可以负担多个进程的(20多个),这样我可以让这台电脑负担3或4个tomcat,这样tomcat的容量就慢慢提升(不太懂),这时前端一个nginx或者Apache,将所有的请求都推到tomcat上,每个tomcat都要进行调优(怎么调优?1.使用64位的tomcat和jdk;2.开启server模式;3.通过-Xms和-Xmx设置初始对大小和最大堆大小,通常将两个值设置位一样,避免堆空间不断增大和缩小所带来的性能损耗;4.启用gzip压缩;5.通过maxThreads增加tomcat的最大并发数,将其设置为500。)tomcat里面加载的都是咋门这个同步的java代码!
3.数据库
这时服务器这一层,万一今天一天的访问量是十万条,或者别的网站(笑)想攻击咱们,用了一个js for循环疯狂访问我们的网站,30秒内让所有的tomcat全部宕完,所以做得好,运维人员还得装一些这个keeploved,这时一个管理软件可以自动管理这个tomcat的情况,如果tomcat挂了,可以给你发短信/发邮件提醒你解决问题。这时服务器这一层,除过以上的,还有就是网站详情页使用静态化了,价格等信息走缓存了,大量的留言评论,用户买了件东西,会去想评论,结果看不见评论,是不是就觉得这个商品是骗人的,也就会造成用户流失;所以留言评论得与数据库交互,需要不停的更新,这时候就是用到了这个mongodb,他关系单一,存储量有很大,有了非关系型数据库,关系型数据库也得用,关系型数据库中mysql的读写分离,就不用说,肯定得有,在加定时器定时备份。除此之外,在做好点,双十一用户买东西,系统挂了,会造成用户丢失,(所以品牌效应很重要)。有的公司为了迎接双十一,直接采用集群服务,服务器备份多个,从三十个增加到60个,外加10个备份,数据库服务备份多个,可即便是这个服务器也会造成宕机,主服务器第一个nginx先挂掉,三十个服务器跟着挂掉,主服务器挂了,从服务器的哨兵检测到挂了,从服务器开始启动,起一个挂一个,起一个挂一个,这个就是雪崩(解决方式这个时候,最好在入口层将流量拒绝,然后再将重启。如果是redis/memcache这种服务也挂了,重启的时候需要注意“预热”,并且很可能需要比较长的时间。),[秒杀和抢购的场景,流量往往是超乎我们系统的准备和想象的]为了防范这些东西,所以通过一个算法,当访问量上限,所有的http请求全部拒绝,告诉用户当前服务其繁忙.所以以前的12306挂了,现在情况好点了。
总结来说从浏览器到后台java代码,再到数据库。
二、秒杀
秒杀的商业目的是什么?吸引大量的用户,本质是持续的时间长一点。一个秒杀或者抢购页面,通常分为2个部分,一个是静态的HTML等内容,另一个就是参与秒杀的Web后台请求接口。
1.页面
在秒杀的页面,抢购时间不断在倒计时,但是,这时候就有很多用户打开了我们这个抢购网站,它会觉得无聊不停地点我们这个抢购按钮,点击就会走ajax,就会与后台交互,java就会判断时间,但是时间没到,服务器反馈这个抢购请求,这样不处理,秒杀还没开始,服务器先被秒杀了,有多种处理的方式。我们用的是说在浏览器上展示一个假页面,页面上的按钮不走事件,当到了抢购时间,重新生成抢购页面,用户需要刷新页面替换上我们的真实页面。
2.后端接口
当我们秒杀的东西比如说10台苹果笔记本电脑,使用roundom随机数,这个时候请求很多呀,我不可能处理多个请求,这个时候就得使用单线程(用什么sql*:没听清),一个请求一个请求进来,使用随机数匹配,过滤掉过多的请求。而当我们秒杀的东西比较多,是一瞬间的事情,这个时候就不能用随机数了,这个处理方式,前边的方式都是一样的,把所有东西放到消息队列里面,redis都不好使了,为什么呢?比如说一个用户抢到东西了,所有的东西都加上synchronized都变成单线程了,用户的商品放到redis中去了,提交订单完成支付,完成发货,而这是针对量比较少的情况,比如说我的产品量比较大,秒到产品存到redis中是没有问题的,但是一旦redis用完之后,假设这时候有10000人进行支付,支付要与数据库交互(动态生成随机下单页面URL为了避免用户直接访问下单页面URL,需要将该URL动态化,即使秒杀系统的开发者也无法在秒杀开始前访问下单页面的URL。办法是在下单页面URL加入由服务器端生成的随机数作为参数,在秒杀开始的时候才能得到。
) 这个时候就使用jms消息队列,让jms处理这个请求。