调优点
调优涉及到3个方面:
- service prodiver端即服务提供者;
- service facade端即服务消费端(按照J2EE的标准称呼叫facade,还有人喜欢叫proxy端,消费端是中国人的说法);
- mysql端
service provider端
去tomcat改用undertow
在service provider端,不用tomcat而改用undertow,因为undertow是nio的,它特别适合高并发场景,而且undertow可以结合操作系统底层的jni调用使得java容器接近ng的反应能力。因此在provider端把tomcat禁用而改用undertow。undertow跟着spring boot版本走,见以下xml。
我这边spring boot用的是:<spring-boot.version>2.3.1.RELEASE</spring-boot.version>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<version>${spring-boot.version}</version>
</dependency>
undertow在application.yml中的配置
我这边是按照4核CPU,8GB内存来配置的。
server:
port: 9081
# tomcat:
# max-http-post-size: -1
# #最小线程数
# min-spare-threads: 150
#最大线程数
# max-threads: 500
#最大链接数
# max-connections: 1000
#最大等待队列长度
# accept-count: 500
undertow:
io-threads: 16
worker-threads: 256
buffer-size: 2048
direct-buffers: true
service facade端配置
去ClosableHttpClient改用OkHttp
其实你只要引入okhttp组件即可,在spring boot.2.2.x以后都可以用okhttp 4.0.0.
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.0.0</version>
</dependency>
然后改动application.yml中feign的客户端如下:
feign:
okhttp:
enabled: true
httpclient:
enabled: false
max-connections: 1000
max-connections-per-route: 100
启用feign的compress功能它是会导致CPU升高(因此至少要用4核)
feign:
okhttp:
enabled: true
httpclient:
enabled: false
max-connections: 1000
max-connections-per-route: 100
compression:
request:
mime-types: text/xml,application/xml,application/json
min-request-size: 2048
enabled: true
response:
enabled: true
如果有用到hystrix熔断请启用大并发
hystrix:
threadpool:
default:
coreSize: 1000
maximumSize: 2000
maxQueueSize: -1
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
service facade端不需要用undertow,你可以延用tomcat
server:
port: 9081
tomcat:
max-http-post-size: -1
# #最小线程数
min-spare-threads: 150
#最大线程数
max-threads: 500
#最大链接数
max-connections: 1000
#最大等待队列长度
accept-count: 500
# undertow:
# io-threads: 16
# worker-threads: 256
# buffer-size: 2048
# direct-buffers: true
max-http-header-size: 10240000
hytrix端采用釠饿加载机制
spring cloud, dubbo和最早的ejb一样,都是远程方法调用。
远程方法调用在第一次调用时我们把它称为“寻址”,这个过程是一个network i/o的过程,它会很漫长。
一旦建立上的第一次调用联接后,它的后续访问是很快的,基本都是毫秒级的。因此第一次这种远程方法调用都会超过容忍极限。
在以前远古ejb时代,我们为了让这个“寻址过程”加速,是会在ejb的残根"stub“上对session facade bean把它的context.lookUp("jndi name");放入servlet的init方法中去的。而在我们现代化的spring cloud中也有一种叫饿加载机制以实现相同的原理:
ribbon:
eager-load:
enabled: true
clients: spring-appliation-name1,spring-application-name2
mysql端调优
一般来说service facade(api/proxy)层是不会访问db的,最最多会访问redis、mongo一类。同时我们的nacos也连着mysql。因此对于spring cloud所要涉及到的db操作,mysql中有几个值将决定着spring cloud的读写性能,而且这几个值又对spring cloud的grpc效率影响特别严重。
我仅仅按照mysql位于8C CPU, 16GB内存,硬盘为固态硬盘即SSD来调就可以到达千级TPS(3,800TPS),它们是:
- max_allowed_packet = 256M
-
innodb_buffer_pool_size=4G
-
innodb_buffer_pool_load_at_startup=1
-
innodb_buffer_pool_dump_at_shutdown=1
-
innodb_lock_wait_timeout = 60
-
innodb_io_capacity_max = 8000 #早其SSD或者是“高速云盘”,这个值设4000
-
innodb_io_capacity = 8000 #早其SSD或者是“高速云盘”,这个值设4000
innodb_flush_method = O_DIRECT
innodb_file_format = Barracuda
join_buffer_size=2097152
read_buffer_size=1M
tmp_table_size = 67108864
max_heap_table_size = 256M
innodb_buffer_pool_chunk_size = 256M
innodb_buffer_pool_instances = 8
innodb_thread_concurrency = 4
innodb_flush_log_at_trx_commit=2
#skip-grant-tables
transaction_isolation=READ-COMMITTED
#from old-139 it is a default isolation level of mysql, we do not suggest use the default only difference with READ-COMMITTED is select for update but for other things is the same
#transaction_isolation = REPEATABLE-READ
#skip-grant-tables
innodb_log_buffer_size = 16M #致命增加写的效率
innodb_log_file_size = 128M #致命增加写的效率