服务器springboot

高并发优化方案

2017-10-27  本文已影响192人  code_nerd

高并发

QPS

每秒处理请求数


优化方案

流量优化

防盗链处理

盗链是指在自己的页面上展示一些并不在自己服务器上的内容。如图片、音乐、视频、软件
防止别人通过技术手段绕过本站的资源展示页,盗用本站资源,使资源连接失效

根据referer或者签名,网站可以检测目标网页访问的来源,如果是资源文件则可以跟踪到显示它的网页地址。
nginx 模块ngx_http_referer_module用于阻挡来源非法的域名请求
nginx 指令valid_referers,全局变量$invalid_referer

//nginx 防盗链配置
location ~* \.(gif|jpg|png|bmp)$ {
        valid_referers none blocked *.domain.com;
//    valid_referers none blocked server_name 
        if ($invalid_referer) {//如果不在白名单
                 return 403;
                #rewrite ^/ http://www.ttlsa.com/403.jpg;
        }
    }
// none :表示referer来源为空的情况
// blocked:referer来源不为空的情况,但是里面的值被代理或者防火墙删除了
// server_name:白名单

php curl伪造referer绕过上述防盗链

使用nginx 的 ngx_http_secure_link_module 模块进行防盗链

nginx 配置如下

location /img/ {
                # 两个arg参数由请求获得
                secure_link $arg_md5,$arg_expires;
                # secret 为加密字符串 uri为访问的路由
                secure_link_md5 secret$arg_expires$uri;


                if ($secure_link = "") {
                        return 403;
                }

                if ($secure_link = "0") {
                        return 410;
                }
        }

php代码如下

//加密字符串 和nginx一致
$secret = "secret";
$uri = "/img/a.txt";
$expire = time();
//加密顺序要和nginx的配置一致
$md5 = base64_encode(md5($secret.$expire.$uri,true));
$md5 = strtr($md5, '+/', '-_');
$md5 = str_replace('=', '', $md5);
$url = "http://bd.test.com/img/a.txt?md5={$md5}&expires={$expire}";

前端优化

减少http请求

$src = 'https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png';
$img_info = getimagesize($src);
$base = base64_encode(file_get_contents($src)); //该base64 也可以用于css
$img_src = "data:{$img_info['mime']};base64," . $base;
exit("![]({$img_src})");

启用浏览器缓存和文件压缩

http缓存机制

缓存分类

相关header
优先级 pragma > cache-control > expires

协商缓存header

// php 模拟nginx 的304
$since = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
$lefttime = 3600;
if (strtotime($since) + $lefttime > time()) {
    header('HTTP/1.1 304 Not Modified');
    exit;
}
header('Last-Modified: ' . gmdate('D,d M Y H:i:s', time() . ' GMT'));
echo time();
nginx配置缓存策略

add_header指令:添加状态码为2xx和3xx的响应头信息
add_header name value [always];
可以设置 pragma/expires/cache-control 可以继承
expires指令:通知浏览器过期时长
expires time;
为负值时,表示cache-control:no-cache
为正值时,表示cache-control:max-age=指定时间

location ~* \.(gif|jpg|png|bmp)$ {
  expires 30d;# 表示遇到上述图片时,告诉浏览器缓存30天
  expires 12h;# 缓存12小时
  etag off;#关闭etag
  add_header cache-control max-age=3600;#缓存3600
}
前端代码和资源压缩

cdn加速

相关概念
什么是cdn:content dilivery network,内容分发网络。可以根据情况,将用户请求导向最近的节点。
使用cdn的优势:本地cache加速,提高站点访问速度,分担网络流量,节省带宽

建立独立图片服务器

分担web服务器的io负载,提高性能和稳定性
能够专门对图片服务器进行优化,减少带宽成本,提高访问时间
提高可扩展,提高图片吞吐
采用独立域名,突破浏览器同一域名并发连接数限制。要处理,如何进行上传图片和图片同步


服务端优化

动态语言静态化

  • 什么是动态语言静态化
    将现有php等动态语言的逻辑代码生成为静态html文件,用户访问动态脚本重定向到静态html文件的过程,对于实时性要求不高的页面
  • 为什么要静态化
    动态脚本通常会做逻辑计算和数据查询,访问量大时,服务器压力越大
    访问量大时会造成cpu负载过高,数据库压力过大,
    静态化可以减低逻辑处理压力,降低数据库服务器查询压力
  • 静态化实现方式
    使用模版引擎
    利用ob系列函数
    ob_start 打开输出控制缓冲
    ob_get_contents 返回输出缓冲区内容
    ob_clean 清空输出缓冲
    ob_end_flush 冲刷到缓冲区,并关闭
<?php

$cache_name = md5(__FILE__) . '.html';//生成缓存名称,通常用hash值

$cache_lefttime = 3600;//缓存过期时间

//判断缓存文件是否存在,缓存是否过期,html内容是否被修改
if (filectime(__FILE__) <= filectime($cache_name) && file_exists($cache_name) && filectime($cache_name) + $cache_lefttime > time()) {
    include $cache_name;
    exit;
}
ob_start();//开启缓存
?>
    <p>this is ob_cache</p>
<?php

$content = ob_get_contents();//获取缓存内容

ob_end_flush();//将缓存冲到浏览器

$handle = fopen($cache_name, 'w');//打开文件

fwrite($handle, $content);//写入内容

fclose($handle);//关闭文件

动态语言并发处理

概念理解

进程

进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调用的基本单位,是操作系统的基础。一个执行中的程序
进程的三态模型:多道程序系统中,进程在处理器上交替运行,状态不断发生变化;主要有运行、就绪、阻塞三种状态。

线程

由于用户的并发请求,为每一个请求都创建一个进程显然是不合理的。从系统资源开销的方面和效率上,引入线程的概念。
线程,有时被称为轻量级进程,是程序执行流的最小单元。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源。线程可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建或撤销另
线程的三种状态:就绪,阻塞和运行

线程和进程的区别
协程

协程是一种用户态的轻量级的线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文切换非常快。

线程和协程的区别
多进程

同一时间里,同一计算机系统中如果允许两个或两个以上的进程处于允许状态,就是多进程。

多线程

线程就是把一个进程分成很多片,每一片可以是一个独立的流程
与多进程的区别是只会使用一个进程的资源,线程间可以直接通信

同步阻塞模型

最早的服务器程序都是通过多进程,多线程来解决并发io问题,一个请求创建一个进程,然后子进程进入循环同步阻塞与客户端进行交互,收发数据。

异步非阻塞

现在各种高并发异步io的服务器程序都是基于epoll实现的。
io复用异步阻塞程序使用经典reactor模型,reactor本身不处理任何数据收发,只是可以监听一个socket句柄的时间变化

php并发编程

数据库优化

数据库缓存

缓存需要考虑的问题:缓存方式的选择,缓存场景的选择,缓存数据的实时性,缓存数据的稳定性

mysql查询缓存

sql文本和查询结果的映射,sql必须完全一致(mysql内部使用hash码对应),才能使用缓存。
query_cache_type
查询缓存有0、1、2。0表示不使用查询缓存,1表示始终使用查询缓存,2表示按需使用查询缓存。

mysql查询优化

数据库服务器架构优化
数据库表结构优化
索引优化
sql优化

web服务器优化

7层负载均衡

基于url应用层信息的均衡操作

优点
nginx负载均衡
内置策略
扩展策略:fair策略、通用hash、一致性hash
http{
      upstream cluster{
            server srv1;
            server srv2;
      }
      server{
            listen 80;
            location / {
                    proxy_pass http://cluster;
            }
      }
}
//以下为示例
 upstream cluster{
                #ip_hash;#根据hash,因ip一致所以拿到同一个机器
                server 127.0.0.1:8080 weight=10;# 权重 轮询从大到小,顺序8081,8080,8082
                server 127.0.0.1:8081 weight=13;
                server 127.0.0.1:8082 weight=8;
        }
server {
    listen       8083;
    server_name  localhost;
    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;
    location / {
        proxy_pass http://cluster;# 这里的cluster与上面的cluster一致
    }
}
# 服务器1
server {
    listen       8080;
    server_name  localhost;
    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;
    location / {
        add_header REAL_SERVER 8080;#在响应头里查看,区别server
       root   /usr/share/nginx/html;
        index  index.html index.php index.htm;

    }
}
# 服务器2
server {
    listen       8081;
    server_name  localhost;
    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;
    location / {
        add_header REAL_SERVER 8081;
       root   /usr/share/nginx/html;
        index  index.html index.php index.htm;

    }
}
# 服务器3
server {
    listen       8082;
    server_name  localhost;
    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;
    location / {
        add_header REAL_SERVER 8082;
       root   /usr/share/nginx/html;
        index  index.html index.php index.htm;

    }
}

4层负载均衡

通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终的内部服务器
lvs实现服务器集群有三种方式NAT、DR和TUN模式

上一篇下一篇

猜你喜欢

热点阅读