常用网络协议性能调研

1.调研目的

解决接口大并发量情况下,接口响应速度问题,提升接口QPS,主要方向在使用netty长连接、websocket协议、http2.0优化网络请求。

2.调研方向

2.1 netty长连接

http1.1默认支持tcp长连接,使用netty长连接在根本上没有太大区别。不做深入调研。

2.2 websocket

websocket最大的特点是建立服务器和客户端的平等对话,能够让服务器主动向客户端推送消息。与我们的调研目的不相符,不做深入调研。

2.3 HTTP/2

HTTP/2是现行的HTTP/1.x的替代,但它不是重写,HTTP方法/状态码/语义都与HTTP/1.x一样。HTTP/2基于SPDY,专注于性能,最大的一个目标是在用户和网站间只用一个连接(connection)。HTTP/2通过多路复用、二进制流、Header压缩等特性,极大的提高了性能。

HTTP/1.1和HTTP/2的区别,可以通过 https://http2.akamai.com/demo 直观感受。

HTTP/1.1和HTTP/2的区别

综合上述,使用HTTP/2代替HTTP/1.1以提高接口响应的速度,以达到提高qps的目的是此次调研的方向

3.调研过程

3.1 HTTP/2相对于HTTP/1.1解决的问题

连接复用问题:

HTTP/1.1解决了HTTP/1.0的短连接问题,默认使用tcp长连接,减少了客户端请求接口数据时建立tcp连接的开销,但是HTTP/1.1协议中浏览器客户端在同一时间,针对同一域名下的的请求有一定的数量限制,超出限制会请求会被阻塞,一些网站围了解决此问题,配置多个静态资源CDN域名。HTTP/2通过多路复用的方式解决了此问题。

HTTP/1.1队头阻塞问题:

HTTP1.1允许客户端不用等待上一次请求的结果,就可以发起下一次请求,但是要求服务器必须按照接收请求的顺序响应客户端的请求,因此一旦队头请求出现延迟,会影响连接中所有的请求响应。HTTP/2基于多路复用+二进制分层帧的机制,使服务的请求和响应可以实现乱序发送,解决了此问题。

报头压缩

HTTP1.1对于HTTP1.0的很多功能优化和扩充其实是增加更多的请求头和响应头来实现的,一次请求的头部占有很大开销,HTTP/2的报头压缩,基于专门为首部压缩而设计的HPACK算法,能够很好的降低协议的开销。

3.2 HTTP2与HTTP/1.1的接口性能测试对比

3.2.1 服务端功能及代码

框架基于springboot2.3.1.RELEASE

1.编写一个用于测试的接口,针对每个请求会延迟100ms响应,对于特殊请求延迟500ms响应

@RestController
public class IndexController {
 
    private static Integer oneNumber = 0;
    private static Integer twoNumber = 0;
 
    @GetMapping("/hello")
    public String testHello(@RequestParam String key) {
        try {
            if ("1".equals(key)) {
                oneNumber ++;
            }
            if ("2".equals(key)) {
                twoNumber ++;
            }
            if (("1".equals(key) && oneNumber % 100 == 0) || ("2".equals(key) && twoNumber % 100 == 0)) {
                Thread.sleep(500L);
            } else {
                Thread.sleep(100L);
            }
            System.out.println("请求响应 key:" + key);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello world";
    }
}

IndexController.java

2.设置监听8443端口,使用HTTP/2协议

Jar包依赖:


    org.springframework.boot
    spring-boot-starter-web
    
    
        
            org.springframework.boot
            spring-boot-starter-tomcat
        
    

 

    
    org.springframework.boot
    spring-boot-starter-undertow

应用启动参数配置

#端口号
server.port=8443
#ip地址
server.address=0.0.0.0
#启用HTTP响应压缩
server.compression.enabled=true
# 启用http2
server.http2.enabled=true
# 启用ssl
server.ssl.enabled=true
#证书位置
server.ssl.key-store=classpath:keystore.p12
# 证书密码
server.ssl.key-store-password=123456
# 证书类型
server.ssl.key-store-type= PKCS12
# 协议类型
server.ssl.protocol=TLSv1.2
server.ssl.key-alias=undertow

注:这里需要生成一个密钥,因为HTTP2必须基于HTTPS才能使用

3.增加一个监听8080端口,使用HTTP/1.1协议

@Component
public class CustomizationBean implements WebServerFactoryCustomizer {
 
    @Override
    public void customize(UndertowServletWebServerFactory factory) {
        factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
            @Override
            public void customize(Undertow.Builder builder) {
                builder.addHttpListener(8080, "0.0.0.0");
            }
        });
 
    }
}

3.2.2 使用Jmeter测试接口(测试HTTP/2需要配置插件)

线程数/单个线程请求次数 HTTP/1.1平均响应时间(ms) HTTP/2平均响应时间(ms)
10/500 187 141
200/30 520 246
600/10 1185 571

具体数据如图:
线程数10,单个线程请求次数500时分别对应HTTP/1.1、HTTP/2的呈现情况。

HTTP/1.1

HTTP/2

线程数200,单个线程请求次数30时分别对应HTTP/1.1、HTTP/2的呈现情况。


HTTP/1.1

HTTP/2

线程数600,单个线程请求次数10时分别对应HTTP/1.1、HTTP/2的呈现情况。


HTTP/1.1

HTTP/2

4.调研结果

经过上述实验,对比使用HTTP/2及HTTP/1.1协议,在性能优化方面有很大提升,后续可以考虑将HTTP/1.1协议替换为HTTP/2协议。

上述实验使用的是mac笔记本实验,实验接口设置的100次请求平均sleep 104ms,而最后的平均响应时间HTTP/1.1达到了1185ms,HTTP/2达到了571ms,说明请求瓶颈在网络传输上,因此造成接口性能的优化能够达到原先一倍的情况,实际情况应该是网络传输效率HTTP2相对于HTTP/1.1能有很大的提高。实际使用到项目上时,需要考虑网络传输效率提高后对服务器处理请求造成的压力,整体请求的效果优化可能达不到上面实验中翻倍的提升情况。

5.使用风险

使用HTTP/2协议使用了多路复用解决了应用层队头阻塞的问题,建立的TCP连接数更加的少,客户端和服务器之间的数据传输在单个TCP连接上能跑进行更多传输,是HTTP/2的优势,同时也是HTTP/2的劣势,一旦发生数据包丢失的情况,整条TCP连接上的数据传输都会受到影响,这就是TCP的队头阻塞,此时HTTP/2就会受到很大影响。

你可能感兴趣的:(常用网络协议性能调研)