大并发下listen的连接完成对列backlog太小导致客户超时,服务器效率低下
2011-11-17 12:37
337 查看
代码就是之前论坛发过的一个epoll代码,根据需要改了就是服务端send的参数。。如下:
/*-------------------------------------------------------------------------------------------------
gcc -o httpd httpd.c -lpthread
author: wyezl
2006.4.28
---------------------------------------------------------------------------------------------------*/
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define PORT 8888
#define MAXFDS 5000
#define EVENTSIZE 100
#define BUFFER "HTTP/1.1 200 OK\r\nContent-Length: 5\r\nConnection: close\r\nContent-Type: text/html\r\n\r\nHello"
int epfd;
void *serv_epoll(void *p);
void setnonblocking(int fd)
{
int opts;
opts=fcntl(fd, F_GETFL);
if (opts < 0)
{
fprintf(stderr, "fcntl failed\n");
return;
}
opts = opts | O_NONBLOCK;
if(fcntl(fd, F_SETFL, opts) < 0)
{
fprintf(stderr, "fcntl failed\n");
return;
}
return;
}
int main(int argc, char *argv[])
{
int fd, cfd,opt=1;
struct epoll_event ev;
struct sockaddr_in sin, cin;
socklen_t sin_len = sizeof(struct sockaddr_in);
pthread_t tid;
pthread_attr_t attr;
epfd = epoll_create(MAXFDS);
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
{
fprintf(stderr, "socket failed\n");
return -1;
}
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt, sizeof(opt));
memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = htons((short)(PORT));
sin.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0)
{
fprintf(stderr, "bind failed\n");
return -1;
}
if (listen(fd, 32) != 0)
{
fprintf(stderr, "listen failed\n");
return -1;
}
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
if (pthread_create(&tid, &attr, serv_epoll, NULL) != 0)
{
fprintf(stderr, "pthread_create failed\n");
return -1;
}
while ((cfd = accept(fd, (struct sockaddr *)&cin, &sin_len)) > 0)
{
setnonblocking(cfd);
ev.data.fd = cfd;
ev.events = EPOLLIN | EPOLLET | EPOLLERR | EPOLLHUP | EPOLLPRI;
epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
//printf("connect from %s\n",inet_ntoa(cin.sin_addr));
//printf("cfd=%d\n",cfd);
}
if (fd > 0)
close(fd);
return 0;
}
void *serv_epoll(void *p)
{
int i, ret, cfd, nfds;;
struct epoll_event ev,events[EVENTSIZE];
char buffer[512];
while (1)
{
nfds = epoll_wait(epfd, events, EVENTSIZE , -1);
//printf("nfds ........... %d\n",nfds);
for (i=0; i<nfds; i++)
{
if(events[i].events & EPOLLIN)
{
cfd = events[i].data.fd;
ret = recv(cfd, buffer, sizeof(buffer),0);
//printf("read ret..........= %d\n",ret);
ev.data.fd = cfd;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, cfd, &ev);
}
else if(events[i].events & EPOLLOUT)
{
cfd = events[i].data.fd;
// send第三个参数改为客户请求的字节数
ret = send(cfd, BUFFER, atoi(buffer), 0);
//printf("send ret...........= %d\n", ret);
ev.data.fd = cfd;
epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, &ev);
close(cfd);
}
else
{
cfd = events[i].data.fd;
ev.data.fd = cfd;
epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, &ev);
close(cfd);
}
}
}
return NULL;
}
复制代码
客户的测试代码就是<Unix 网络编程>中30章的那个client代码。
问题表现就是epoll这个的服务端对10000的并发请求处理特别慢,甚至还出现很多客户连接超时的情况!但是顺序的一个个请求没有问题。
测试如下:
首先是1个进程,顺序10000个请求。。服务端没问题,很快速完成。
然后是10000个进程,每个进程1个请求,前面都还正常,可是过一会服务端accept就阻塞了,大概有1-2s,之后又返回,有时候还会出现客户端连接超时的问题,但是这样测30章那个线程池(300个线程)的服务端代码,不管怎么测都不会有问题。
按理说accept应该能一直返回才对呀,为什么中途会阻塞呢?是内核参数问题?
之前也试过把listenfd也添加到epoll里,listenfd不是ET模式。。也有这样的问题。。
分析了很多可能:
epoll本身处理效率的问题(这个自己都不信)
服务端完成客户的处理请求太耗时,导致没有时间让accept返回其他客户连接(这个最简的单处理,应该也不会)
单台机器测试,所以产生了太多的TIME_WAIT导致客户无法连接导致超时(之前以为是这个原因)
内核的一些限制问题,服务端不能同时处理太多连接(可能的原因)
最终才发现真正原因!!!
原来上面这个服务器代码listen指定的backlog连接完成队列参数太小,只有32,导致高并发的时候,服务器的连接完成队列在极短的时间内被填满了,而accept的处理速度跟不上队列填满的速度,导致队列始终是满的,然后就不理会客户的其他连接请求,导致了客户connect超时,并且处理效率低下。
而线程池的backlog有1024,不过受限于内核参数的默认值最大128,所以线程池这个的backlog实际是128(见man listen),再加上300个线程,每个线程独自accpet,所以能很快从完成队列中取得连接,客户的connect也不会超时了,如果把线程数改为1个,客户连接也会超时。
下面是man listen中的引用
QUOTE:
If the backlog argument is greater than the value in /proc/sys/net/core/somaxconn, then it is silently truncated to that value; the default value in this file is
128. In kernels before 2.4.25, this limit was a hard coded value, SOMAXCONN, with the value 128.
详细信息可以man listen。同时man tcp里面有很多限制对服务器来说需要改的。
网上看到的一个修改服务器参数的:http://hi.baidu.com/yupanlovehlq ... cc2155faf2c099.html
QUOTE:
$ /proc/sys/net/core/wmem_max
最大socket写buffer,可参考的优化值:873200
$ /proc/sys/net/core/rmem_max
最大socket读buffer,可参考的优化值:873200
$ /proc/sys/net/ipv4/tcp_wmem
TCP写buffer,可参考的优化值: 8192 436600 873200
$ /proc/sys/net/ipv4/tcp_rmem
TCP读buffer,可参考的优化值: 32768 436600 873200
$ /proc/sys/net/ipv4/tcp_mem
同样有3个值,意思是:
net.ipv4.tcp_mem[0]:低于此值,TCP没有内存压力.
net.ipv4.tcp_mem[1]:在此值下,进入内存压力阶段.
net.ipv4.tcp_mem[2]:高于此值,TCP拒绝分配socket.
上述内存单位是页,而不是字节.可参考的优化值是:786432 1048576 1572864
$ /proc/sys/net/core/netdev_max_backlog
进入包的最大设备队列.默认是300,对重负载服务器而言,该值太低,可调整到1000.
$ /proc/sys/net/core/somaxconn
listen()的默认参数,挂起请求的最大数量.默认是128.对繁忙的服务器,增加该值有助于网络性能.可调整到256.
$ /proc/sys/net/core/optmem_max
socket buffer的最大初始化值,默认10K.
$ /proc/sys/net/ipv4/tcp_max_syn_backlog
进入SYN包的最大请求队列.默认1024.对重负载服务器,增加该值显然有好处.可调整到2048.
$ /proc/sys/net/ipv4/tcp_retries2
TCP失败重传次数,默认值15,意味着重传15次才彻底放弃.可减少到5,以尽早释放内核资源.
$ /proc/sys/net/ipv4/tcp_keepalive_time
$ /proc/sys/net/ipv4/tcp_keepalive_intvl
$ /proc/sys/net/ipv4/tcp_keepalive_probes
这3个参数与TCP KeepAlive有关.默认值是:
tcp_keepalive_time = 7200 seconds (2 hours)
tcp_keepalive_probes = 9
tcp_keepalive_intvl = 75 seconds
意思是如果某个TCP连接在idle 2个小时后,内核才发起probe.如果probe 9次(每次75秒)不成功,内核才彻底放弃,认为该连接已失效.对服务器而言,显然上述值太大. 可调整到:
/proc/sys/net/ipv4/tcp_keepalive_time 1800
/proc/sys/net/ipv4/tcp_keepalive_intvl 30
/proc/sys/net/ipv4/tcp_keepalive_probes 3
$ proc/sys/net/ipv4/ip_local_port_range
指定端口范围的一个配置,默认是32768 61000,已够大.
net.ipv4.tcp_syncookies = 1
表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1
表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1
表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout = 30
表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。
net.ipv4.tcp_keepalive_time = 1200
表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
net.ipv4.ip_local_port_range = 1024 65000
表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。
net.ipv4.tcp_max_syn_backlog = 8192
表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_tw_buckets = 5000
表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改为 5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。
一般设置:
1 sudo vi /etc/sysctl.conf
在最下面编辑添加:
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.route.gc_timeout = 100
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_max_syn_backlog = 262144
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_mem = 94500000 915000000 927000000
保存退出
2 sudo /sbin/sysctl -p
/*-------------------------------------------------------------------------------------------------
gcc -o httpd httpd.c -lpthread
author: wyezl
2006.4.28
---------------------------------------------------------------------------------------------------*/
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define PORT 8888
#define MAXFDS 5000
#define EVENTSIZE 100
#define BUFFER "HTTP/1.1 200 OK\r\nContent-Length: 5\r\nConnection: close\r\nContent-Type: text/html\r\n\r\nHello"
int epfd;
void *serv_epoll(void *p);
void setnonblocking(int fd)
{
int opts;
opts=fcntl(fd, F_GETFL);
if (opts < 0)
{
fprintf(stderr, "fcntl failed\n");
return;
}
opts = opts | O_NONBLOCK;
if(fcntl(fd, F_SETFL, opts) < 0)
{
fprintf(stderr, "fcntl failed\n");
return;
}
return;
}
int main(int argc, char *argv[])
{
int fd, cfd,opt=1;
struct epoll_event ev;
struct sockaddr_in sin, cin;
socklen_t sin_len = sizeof(struct sockaddr_in);
pthread_t tid;
pthread_attr_t attr;
epfd = epoll_create(MAXFDS);
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
{
fprintf(stderr, "socket failed\n");
return -1;
}
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt, sizeof(opt));
memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = htons((short)(PORT));
sin.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0)
{
fprintf(stderr, "bind failed\n");
return -1;
}
if (listen(fd, 32) != 0)
{
fprintf(stderr, "listen failed\n");
return -1;
}
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
if (pthread_create(&tid, &attr, serv_epoll, NULL) != 0)
{
fprintf(stderr, "pthread_create failed\n");
return -1;
}
while ((cfd = accept(fd, (struct sockaddr *)&cin, &sin_len)) > 0)
{
setnonblocking(cfd);
ev.data.fd = cfd;
ev.events = EPOLLIN | EPOLLET | EPOLLERR | EPOLLHUP | EPOLLPRI;
epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
//printf("connect from %s\n",inet_ntoa(cin.sin_addr));
//printf("cfd=%d\n",cfd);
}
if (fd > 0)
close(fd);
return 0;
}
void *serv_epoll(void *p)
{
int i, ret, cfd, nfds;;
struct epoll_event ev,events[EVENTSIZE];
char buffer[512];
while (1)
{
nfds = epoll_wait(epfd, events, EVENTSIZE , -1);
//printf("nfds ........... %d\n",nfds);
for (i=0; i<nfds; i++)
{
if(events[i].events & EPOLLIN)
{
cfd = events[i].data.fd;
ret = recv(cfd, buffer, sizeof(buffer),0);
//printf("read ret..........= %d\n",ret);
ev.data.fd = cfd;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd, EPOLL_CTL_MOD, cfd, &ev);
}
else if(events[i].events & EPOLLOUT)
{
cfd = events[i].data.fd;
// send第三个参数改为客户请求的字节数
ret = send(cfd, BUFFER, atoi(buffer), 0);
//printf("send ret...........= %d\n", ret);
ev.data.fd = cfd;
epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, &ev);
close(cfd);
}
else
{
cfd = events[i].data.fd;
ev.data.fd = cfd;
epoll_ctl(epfd, EPOLL_CTL_DEL, cfd, &ev);
close(cfd);
}
}
}
return NULL;
}
复制代码
客户的测试代码就是<Unix 网络编程>中30章的那个client代码。
问题表现就是epoll这个的服务端对10000的并发请求处理特别慢,甚至还出现很多客户连接超时的情况!但是顺序的一个个请求没有问题。
测试如下:
首先是1个进程,顺序10000个请求。。服务端没问题,很快速完成。
然后是10000个进程,每个进程1个请求,前面都还正常,可是过一会服务端accept就阻塞了,大概有1-2s,之后又返回,有时候还会出现客户端连接超时的问题,但是这样测30章那个线程池(300个线程)的服务端代码,不管怎么测都不会有问题。
按理说accept应该能一直返回才对呀,为什么中途会阻塞呢?是内核参数问题?
之前也试过把listenfd也添加到epoll里,listenfd不是ET模式。。也有这样的问题。。
分析了很多可能:
epoll本身处理效率的问题(这个自己都不信)
服务端完成客户的处理请求太耗时,导致没有时间让accept返回其他客户连接(这个最简的单处理,应该也不会)
单台机器测试,所以产生了太多的TIME_WAIT导致客户无法连接导致超时(之前以为是这个原因)
内核的一些限制问题,服务端不能同时处理太多连接(可能的原因)
最终才发现真正原因!!!
原来上面这个服务器代码listen指定的backlog连接完成队列参数太小,只有32,导致高并发的时候,服务器的连接完成队列在极短的时间内被填满了,而accept的处理速度跟不上队列填满的速度,导致队列始终是满的,然后就不理会客户的其他连接请求,导致了客户connect超时,并且处理效率低下。
而线程池的backlog有1024,不过受限于内核参数的默认值最大128,所以线程池这个的backlog实际是128(见man listen),再加上300个线程,每个线程独自accpet,所以能很快从完成队列中取得连接,客户的connect也不会超时了,如果把线程数改为1个,客户连接也会超时。
下面是man listen中的引用
QUOTE:
If the backlog argument is greater than the value in /proc/sys/net/core/somaxconn, then it is silently truncated to that value; the default value in this file is
128. In kernels before 2.4.25, this limit was a hard coded value, SOMAXCONN, with the value 128.
详细信息可以man listen。同时man tcp里面有很多限制对服务器来说需要改的。
网上看到的一个修改服务器参数的:http://hi.baidu.com/yupanlovehlq ... cc2155faf2c099.html
QUOTE:
$ /proc/sys/net/core/wmem_max
最大socket写buffer,可参考的优化值:873200
$ /proc/sys/net/core/rmem_max
最大socket读buffer,可参考的优化值:873200
$ /proc/sys/net/ipv4/tcp_wmem
TCP写buffer,可参考的优化值: 8192 436600 873200
$ /proc/sys/net/ipv4/tcp_rmem
TCP读buffer,可参考的优化值: 32768 436600 873200
$ /proc/sys/net/ipv4/tcp_mem
同样有3个值,意思是:
net.ipv4.tcp_mem[0]:低于此值,TCP没有内存压力.
net.ipv4.tcp_mem[1]:在此值下,进入内存压力阶段.
net.ipv4.tcp_mem[2]:高于此值,TCP拒绝分配socket.
上述内存单位是页,而不是字节.可参考的优化值是:786432 1048576 1572864
$ /proc/sys/net/core/netdev_max_backlog
进入包的最大设备队列.默认是300,对重负载服务器而言,该值太低,可调整到1000.
$ /proc/sys/net/core/somaxconn
listen()的默认参数,挂起请求的最大数量.默认是128.对繁忙的服务器,增加该值有助于网络性能.可调整到256.
$ /proc/sys/net/core/optmem_max
socket buffer的最大初始化值,默认10K.
$ /proc/sys/net/ipv4/tcp_max_syn_backlog
进入SYN包的最大请求队列.默认1024.对重负载服务器,增加该值显然有好处.可调整到2048.
$ /proc/sys/net/ipv4/tcp_retries2
TCP失败重传次数,默认值15,意味着重传15次才彻底放弃.可减少到5,以尽早释放内核资源.
$ /proc/sys/net/ipv4/tcp_keepalive_time
$ /proc/sys/net/ipv4/tcp_keepalive_intvl
$ /proc/sys/net/ipv4/tcp_keepalive_probes
这3个参数与TCP KeepAlive有关.默认值是:
tcp_keepalive_time = 7200 seconds (2 hours)
tcp_keepalive_probes = 9
tcp_keepalive_intvl = 75 seconds
意思是如果某个TCP连接在idle 2个小时后,内核才发起probe.如果probe 9次(每次75秒)不成功,内核才彻底放弃,认为该连接已失效.对服务器而言,显然上述值太大. 可调整到:
/proc/sys/net/ipv4/tcp_keepalive_time 1800
/proc/sys/net/ipv4/tcp_keepalive_intvl 30
/proc/sys/net/ipv4/tcp_keepalive_probes 3
$ proc/sys/net/ipv4/ip_local_port_range
指定端口范围的一个配置,默认是32768 61000,已够大.
net.ipv4.tcp_syncookies = 1
表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1
表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1
表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout = 30
表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。
net.ipv4.tcp_keepalive_time = 1200
表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
net.ipv4.ip_local_port_range = 1024 65000
表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。
net.ipv4.tcp_max_syn_backlog = 8192
表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_tw_buckets = 5000
表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改为 5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。
一般设置:
1 sudo vi /etc/sysctl.conf
在最下面编辑添加:
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.route.gc_timeout = 100
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_max_syn_backlog = 262144
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_mem = 94500000 915000000 927000000
保存退出
2 sudo /sbin/sysctl -p
相关文章推荐
- 大并发下listen的连接完成对列backlog太小导致客户超时,服务器效率低下
- sharepoint 2013 打开rdl报表,报表服务器数据库内出错。此错误可能是因连接失败、超时或数据库中磁盘空间不足而导致的
- Reporting Service 2008 “报表服务器数据库内出错。此错误可能是因连接失败、超时或数据库中磁盘空间不足而导致的”
- 不为客户连接创建子进程的并发回射服务器( select实现 )
- 第十九篇:不为客户连接创建子进程的并发回射服务器(select实现)
- 不为客户连接创建子进程的并发回射服务器( poll实现 )
- 第二十篇:不为客户连接创建子进程的并发回射服务器(poll实现)
- 【LoadRunner】场景加压的常见问题①高并发导致超时,连接拒绝等
- 禁用网卡导致连接ESXI服务器超时
- 解决PCoIP连接View 5.0虚拟桌面超时断开导致无法再次登录的问题
- 超时时间已到。在操作完成之前超时时间已过或服务器未响应。 (.Net SqlClient Data Provider)
- MarioTCP:一个单机可日30亿的百万并发长连接服务器
- DPA/Ignite由于DNS问题导致连接不上被监控的数据库服务器
- 超时时间已到。在操作完成之前超时时间已过或服务器未响应
- [SQL Server] 数据库日志文件自动增长导致连接超时的分析
- ORA-12535:TNS连接超时/oracle客户端连接服务器报错解决办法
- 查看服务器tcp连接及服务器并发
- 手机邮箱配置完成后提示无法连接到服务器
- 支付宝获取远程服务器ATN结果,验证是否是支付宝服务器发来的请求是超时导致交易签名被篡改
- Mysql连接数过大导致连接超时的问题