网站在某些业务场景中,可能会存在短时间的高并发情况,瞬时压力有可能给服务器尤其是数据库带来巨大流量,导致数据库cpu占用接近100%,之后所有接口请求响应都会非常慢甚至直接宕机。

那怎么来提高系统在高并发时的吞吐能力呢?

排查慢查询

仔细排查系统中可能会出现的慢查询,进行sql优化,降低其他业务的某个慢查询对数据库的影响,实在无法优化,可以考虑在高并发场景中禁用相关业务功能。

扩容

如果是单机硬件性能不足,系统本身的cpu内存等在高并发下占用率显著提高,那么考虑平行扩容机器,最好用docker等容器化技术,方便部署,同时用NGINX或者云服务提供的负载均衡分流流量,减轻单台机器的压力。

**但是实际很多场景都是单体数据库扛不住流量,加再多机器也无济于事。

限流

你可以针对某个路径的请求进行限流,首先可以根据路径,通过map指令匹配出来, 这样不会影响其他业务。

map $uri $custom_var {
	"正则表达式" 'target';
}

接下来再利用nginx的限流配置,在多余的请求未到达业务模块时就扼杀在大门外。 limit_conn_zone $custom_var zone=per_server:10m;

缓存

缓存分为redis、nginx和http部分

Redis
  1. 将高并发状态下可能影响并发业务的其他数据库低优先级的写入任务(如一些行为数据记录之类)暂停,转而写入Redis中,减轻数据库压力,待高并发时段结束后,利用(定时)脚本,将Redis中的数据同步回数据库中,保证数据不丢失。
  2. 将并发业务中的接口数据尽可能在一次请求后就写入Redis中,后续相同请求进来直接从Redis中取用,减轻数据库压力。
nginx
server {
	proxy_cache_methods GET;
    proxy_ignore_headers Expires X-Accel-Expires Vary Set-Cookie;
    proxy_hide_header Cache-Control;
    proxy_cache_key $cache_key;
    proxy_cache cache_zone;
    proxy_cache_valid 200 301 302 404 1s;
}

利用nginx的proxy_cache_path对响应进行磁盘缓存 proxy_cache_path /nginx_cache/ levels=2:2 keys_zone=cache_zone:20m max_size=1g inactive=1d; 以上配置的含义是将响应结果缓存至磁盘/nginx_cache/位置,key的存储空间名, key的存储空间(或者公用内存空间)的名称是cache_zone及缓存大小是20m,最大的结果缓存空间是1g,缓存资源若1d未访问则缓存失效自动删除。

注: 每个缓存资源都有key和metadata,nginx会开辟一片内存空间存储他们,这样就能快速判断一个请求是否命中或未命中缓存 proxy_cache 启用缓存并指定keys_zone,如果是off表示不使用缓存。

http
  1. 如果系统中有需要微信oauth之类的登录操作,建议将openid缓存至cookie/localStorage中,避免频繁进行oauth。
  2. 在高并发期间,利用http协商缓存,即response响应头中的Cache-control设置一个较大的过期时间max-age=xxx, 这样用户再次发起同样的请求后命中协商缓存就不再走原有业务逻辑进行数据查询。

标签: 缓存, 高并发, nginx, redis

添加新评论

0%