PHP学习心得


打造高并发抢购商品服务

<h2>商品抢购考虑方面</h2> <ul> <li>负载均衡 <ul> <li>有并发的时候,就需要负载均衡,使用nginx做负载均衡</li> </ul></li> <li>redis集群</li> <li>mysql架构 <ul> <li>主从,分库分表</li> </ul></li> <li>静态池 <ul> <li>当用户量比较大时,需要静态池放静态文件,静态文件请求后端接口(可以理解为前后端分离)</li> </ul></li> <li>kafka <ul> <li>消息队列在特大流量时kafka更好,同时处理大型日志,也支持的很好</li> </ul></li> <li>数据缓存引入 <ul> <li>数据更新频率比较慢的,都可以放到缓存中</li> </ul></li> <li>分布式session</li> <li>限流 <ul> <li>通过nginx,限制同一个IP,在某个时间段只能请求多少次。</li> <li>也可以在php代码里写,如首页api,同一个IP,在一秒中访问此次数不能超过多少次</li> </ul></li> <li>熔断、降级 <ul> <li>熔断在微服务里边使用非常广</li> <li>如:一分钟请求阿里接口100次,有60次失败的,就认为阿里服务不可靠了,直接不去请求,进行熔断,返回阿里服务有异常的提示信息</li> </ul></li> <li>反作弊 <ul> <li>商品抢购使用比较多,避免被薅羊毛</li> </ul></li> <li>服务评估 <ul> <li>在某一场景下,需要多少台服务,可以抗住多少用户的并发</li> </ul></li> </ul> <h2>系统要保证的</h2> <ul> <li>可高用,稳定性。因此单台服务器是不稳定的,在挂了的情况,就不能访问系统了,因此需要引入分布式。</li> </ul> <h2>单机服务器网站架构</h2> <ul> <li>架构 <ul> <li>用户访问-&gt;nginx-&gt;PHP-&gt;mysql/redis</li> </ul></li> <li>产生问题 <ul> <li>不抗压,不能解决高可用、稳定性</li> </ul></li> <li>一般使用 <ul> <li>在测试环境开发,不会使用正式环境上。或者用户量很少,系统不太重要才使用单机服务器。</li> </ul></li> </ul> <h2>大型网站架构</h2> <ul> <li> <p>使用集群</p> </li> <li> <p>架构</p> <ul> <li>用户访问</li> <li>通过不同地域,找到距离用户最近的CDN服务器</li> <li>CDN是内容分发</li> <li>如果CDN服务器就内容,直接返回给用户,CDN服务器不再继续向下访问,如不访问nginx服务器。</li> <li> <p>如果数据需要做到实时的,CDN没有数据,会做到回源。CDN服务器转发到真实服务器上去,</p> </li> <li>nginx进行转发,使用负载均衡器</li> <li>mysql集群</li> <li>分库分表</li> <li>图片上传到云服务器</li> <li>异步消息队列</li> <li>服务监控</li> <li>服务器有成千万台,再去找日志,非常不合理</li> <li>服务监控基于日志去做的</li> <li>一个请求过来,从哪个模块到哪个模块,模块和模块之间的关系,有没有连接耗时、有没有请求耗时,有没有跨机房等</li> </ul> </li> </ul> <h2>订单数据比较大,分库分表策略</h2> <ul> <li>先根据用户id进行取模,如取100个模,不同的用户id会落到不同的数据库里</li> <li>库里再根据用户id进行取模,如取1000个模,不同的用户id会落到不同的数据表里</li> </ul> <h2>百度网盘分库分表策略</h2> <ul> <li>如百度图片,几千亿</li> <li>根据用户id做的分库分表</li> </ul> <h2>mysql单表原则上条数</h2> <ul> <li>不能超1千万条。</li> <li>如果单表超过了1千万条,mysql效率会特别低</li> </ul> <h2>负载均衡的方法</h2> <ul> <li>是集群技术的一种应用,它可以将请求负载到多个服务中,从而提供并发处理能力,任何一台服务器故障不影响整体服务,</li> <li>从而也能达到高可用的状态。这也是解决常用并发能力的一种手段,web负载均衡能力是比较常见的一种负载均衡。</li> </ul> <h2>常见的web负载均衡技术</h2> <ul> <li> <p>dns轮训</p> <ul> <li>成本很小,所以小公司用的比较多,但是大公司的话也可以结合dns来做,比如返回的IP可以是一个集群地址(这个VIP下双挂好多服务)</li> <li>缺点:可靠性低,不能做到高可用,负载不均衡</li> </ul> </li> <li>CDN</li> <li>IP负载均衡 <ul> <li>基于tcp ip的,ip负载均衡可以使用硬件也可以使用软件来实现,硬件设备比如F5,软件有:nginx lvs haproxy</li> </ul></li> </ul> <h2>nginx负载均衡模式</h2> <ul> <li>nginx负载均衡配置主要是对proxy_pass和upstream的配置,需要在http模块下配置upstream模块,然后在server模块下配置proxy_pass模块</li> </ul> <pre><code class="language-nginx">upstream mall_proxy { server 127.0.0.1:8182 weight=2; server 127.0.0.1:8382; } location / { proxy_pass http://mall_proxy; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }</code></pre> <ul> <li>轮训模式</li> <li>weight权重模式</li> <li>ip_hash</li> </ul> <h2>nginx负载均衡注意事项</h2> <ul> <li>vue负载端口要改成nginx的proxy的端口号</li> </ul> <h2>PHP实现页面静态化</h2> <ul> <li> <p>教程地址</p> <ul> <li><a href="https://www.imooc.com/learn/330">https://www.imooc.com/learn/330</a></li> </ul> </li> <li>流程 <ul> <li>后台-&gt;自动生成自动化页面 index.html-&gt;后端机器某一个目录-&gt;异步任务,下发到真实的前端机器上</li> </ul></li> </ul> <h2>mysql集群架构</h2> <ul> <li>网站请求的瓶颈在数据</li> <li> <p>一主多从如何保持数据的一致性</p> </li> <li>proxy层配置,如在主库写完的100毫秒内,读从库没有数据,会转发到主去读。如果大于100毫秒,会读从库。</li> <li>mysql检测机制,如果主库和从库没有同步完成,当有读取从库操作时,proxy会转发到主库去读取。</li> <li>原则上,一般主库与从库同步时是在1秒中以内完成,会受到带宽,网络延时影响,因此服务器采用内网通信,同一地区的。</li> <li> <p>主库写完后,写到redis内,如果redis没有,再去读取mysql数据库。</p> </li> <li>mysql单个数据表达到1千万以后,无论怎么优化,如加索引等,读取速度都会非常慢,因此要分库分表。</li> <li>分库分表策略 <ul> <li>判断哪些数据表会特别大,如订单表,商品表</li> <li>使用hash方式,取模操作。</li> </ul></li> <li>-大众点评订单系统分库分表实践</li> <li><a href="https://tech.meituan.com/2016/11/18/dianping-order-db-sharding.html">https://tech.meituan.com/2016/11/18/dianping-order-db-sharding.html</a></li> <li>MySQL(主从配置) <ul> <li><a href="https://www.jianshu.com/p/cfd9bfd6e7f2">https://www.jianshu.com/p/cfd9bfd6e7f2</a></li> </ul></li> </ul> <h2>redis分布式集群</h2> <ul> <li>与mysql分布式集群类似</li> <li> <p>主从模式的弊端</p> <ul> <li>当主库挂了,写就失败,读没有影响,读取从库数据,因此redis使用哨兵模式监听解决此问题</li> </ul> </li> <li>哨兵模式 <ul> <li>redis监听到一台主库挂了,立刻会把其中一台从库服务器(自动),变成主库服务器。哨兵模式是一个独立的进程</li> <li>哨兵模式也是需要多个的,也是为了避免单哨兵模式会挂了,哨兵也会相互监听彼此会挂掉,主要解决高可用</li> <li>数据量很大,大到内存都放不下,redis会进行分片策略处理,不同的主库数据也是不一样的</li> </ul></li> </ul> <h2>redis相关的哨兵模式有相关推荐</h2> <ul> <li><a href="https://www.zhihu.com/question/21419897">https://www.zhihu.com/question/21419897</a></li> <li><a href="https://blog.csdn.net/miss1181248983/article/details/90056960">https://blog.csdn.net/miss1181248983/article/details/90056960</a></li> </ul> <h2>分布式session</h2> <ul> <li>在php.ini配置</li> </ul> <pre><code class="language-php">session.save_handler = redis session.save_path = "tcp:127.0.0.1:6379"</code></pre> <ul> <li>redis分布式,session.save_path换成分布式地址就行了</li> </ul> <h2>kafka集群</h2> <ul> <li>目前主要作为一个分布式的发布订阅式的消息系统使用,常用于业务系统中消息队列,现在大数据领域应用比较广泛。</li> </ul> <h2>服务压力测试以及服务评估</h2> <ul> <li>特别是大公司,是必不可少的环节</li> <li>预估服务的极限承载压力,能抗多少qps,写多少</li> <li>redis集群读qps多少,写多少</li> <li>业务层服务器qps</li> <li>评估方式:压力测试 <ul> <li>ab压力测试</li> <li>边使用ab压力测试,边使用top命令查看服务器压力</li> <li>sysbench</li> <li>mysql压力测试工具</li> <li>redis-benchmark</li> <li>redis压力测试工具</li> </ul></li> </ul> <h2>提升空间</h2> <ul> <li>代码优化,服务器优化,策略优化</li> </ul> <h2>服务限流-php+redis方案</h2> <pre><code class="language-php">$key = 'test_' . time(); // 使用redis 字符串类型自增INCR命令 $get = Cache::inc($key); if ($get &lt;= 500) { // 放行 执行你的业务逻辑代码 return $get; } else { return 0; }</code></pre> <h2>服务限流-nginx+lua+redis高性能方案</h2> <ul> <li>使用openresty,官网地址 <ul> <li><a href="http://openresty.org/cn/">http://openresty.org/cn/</a></li> </ul></li> <li>openresty <ul> <li>基于nignx与lua的高性能web平台,其内部集成了大量精良的lua库,第三方模块以及大多数的依赖项。</li> <li>用于方便地搭建能够处理超高并发、扩展性极高的动态web应用,web服务和动态网关</li> </ul></li> </ul> <h2>服务降级和熔断</h2> <ul> <li>开发高并发服务时,保护系统服务的方式 <ul> <li>缓存、降级、限流</li> </ul></li> <li>为什么需要阶级 <ul> <li>当访问突然间猛增,服务出现如响应时间慢,或不响应或非核心服务影响到核心服务的性能时,</li> <li>仍然需要保证核心服务还是可用的,即使服务是有损服务,所以我们需要服务降级处理</li> </ul></li> <li>降级手段 <ul> <li>从宏观角度来说,可以分为人工降级和自动降级</li> <li>非核心功能人功能降级,把某些非核心功能停掉</li> </ul></li> </ul>

页面列表

ITEM_HTML