性能大比拼

一、创建euraka集群

  1. 创建父项目,包含父pom文件和子项目,并增加依赖,主要是:spring-cloud-starter-parent

    <parent>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-parent</artifactId>
        <version>Camden.RELEASE</version>
    </parent>
    <groupId>com.sohu.tv</groupId>
    <artifactId>spring-cloud-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    
    <modules>
        <module>eureka-test</module>
        <module>provider-test</module>
        <module>consumer-test</module>
    </modules>
    
  2. 创建eureka-test,并在pom添加依赖spring-cloud-starter,spring-cloud-starter-eureka-server

    <parent>
        <groupId>com.sohu.tv</groupId>
        <artifactId>spring-cloud-test</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    
    <artifactId>eureka-test</artifactId>
    <packaging>jar</packaging>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
  3. euraka代码很简单:

    @SpringBootApplication
    @EnableEurekaServer
    public class SpringCloudEurekaApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringCloudEurekaApplication.class, args);
        }
    }
    
  4. euraka-test配置application.yml

    spring: 
      application:
        name: eureka-test
    
    server: 
      port: 8000
    
    eureka:
      instance:
        preferIpAddress: true
        instanceId: ${spring.cloud.client.ipAddress}:${server.port}
    ---
    
    spring: 
      profiles: node1
    
    eureka: 
      client: 
        serviceUrl:
          defaultZone: http://eureka:8000/eureka/,http://eureka2:8000/eureka/
    
    ---
    
    spring: 
      profiles: node2
    
    eureka: 
      client:
        serviceUrl:
          defaultZone: http://eureka2:8000/eureka/,http://eureka3:8000/eureka/
    
    ---
    
    spring: 
      profiles: node3
    
    eureka: 
      client: 
        serviceUrl:
          defaultZone: http://eureka3:8000/eureka/,http://eureka:8000/eureka/
    
  5. 在对应的机器上启动euraka-test,即完成集群创建,启动命令如下:

    nohup /opt/cloud/jdk/bin/java -Dspring.profiles.active=node1 -server -Xmx4g -Xms4g -Xss256k -XX:+UseG1GC -XX:+PrintGCDateStamps -Xloggc:/opt/cloud/gc.log -jar /opt/cloud/eureka-test.jar > /opt/cloud/stdout.log &
    nohup /opt/cloud/jdk/bin/java -Dspring.profiles.active=node2 -server -Xmx4g -Xms4g -Xss256k -XX:+UseG1GC -XX:+PrintGCDateStamps -Xloggc:/opt/cloud/gc.log -jar /opt/cloud/eureka-test.jar > /opt/cloud/stdout.log &
    nohup /opt/cloud/jdk/bin/java -Dspring.profiles.active=node3 -server -Xmx4g -Xms4g -Xss256k -XX:+UseG1GC -XX:+PrintGCDateStamps -Xloggc:/opt/cloud/gc.log -jar /opt/cloud/eureka-test.jar > /opt/cloud/stdout.log &
    

二、增加provider-test

  1. pom很简单:

    <parent>
        <groupId>com.sohu.tv</groupId>
        <artifactId>spring-cloud-test</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    
    <artifactId>provider-test</artifactId>
    <packaging>jar</packaging>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
    
  2. 代码主要是rest接口(hello10:返回10个字符,hello100:返回100个字符,hello1000:返回1000个字符):

    private String c10 = "abcvdfjiel";
    private String c100 = "abcvdfjiel0938271648losdgshaiougoiewnavoienoidsa[yg[0e0u9g-rendsvsatg439098u6y480vb309ja0sv[nsdijfd";
    private String c1000 = "abcvdfjiel0938271648losdgshaiougoiewnavoienoidsa[yg[0e0u9g-rendsvsatg439098u6y480vb309ja0sv[nsdijfdabcvdfjiel0938271648losdgshaiougoiewnavoienoidsa[yg[0e0u9g-rendsvsatg439098u6y480vb309ja0sv[nsdijfddabcvdfjiel0938271648losdgshaiougoiewnavoienoidsa[yg[0e0u9g-rendsvsatg439098u6y480vb309ja0sv[nsdijfdabcvdfjiel0938271648losdgshaiougoiewnavoienoidsa[yg[0e0u9g-rendsvsatg439098u6y480vb309ja0sv[nsdijfddabcvdfjiel0938271648losdgshaiougoiewnavoienoidsa[yg[0e0u9g-rendsvsatg439098u6y480vb309ja0sv[nsdijfdabcvdfjiel0938271648losdgshaiougoiewnavoienoidsa[yg[0e0u9g-rendsvsatg439098u6y480vb309ja0sv[nsdijfddabcvdfjiel0938271648losdgshaiougoiewnavoienoidsa[yg[0e0u9g-rendsvsatg439098u6y480vb309ja0sv[nsdijfdabcvdfjiel0938271648losdgshaiougoiewnavoienoidsa[yg[0e0u9g-rendsvsatg439098u6y480vb309ja0sv[nsdijfddabcvdfjiel0938271648losdgshaiougoiewnavoienoidsa[yg[0e0u9g-rendsvsatg439098u6y480vb309ja0sv[nsdijfdabcvdfjiel0938271648losdgshaiougoiewnavoienoidsa[yg[0e0u9g-rendsvsatg439098u6y480vb309ja0sv[nsdijfdddsds";
    
    @RequestMapping("/hello10")
    public String hello10() {
        return c10;
    }
    
    @RequestMapping("/hello100")
    public String hello100() {
        return c100;
    }
    
    @RequestMapping("/hello1000")
    public String hello1000() {
        return c1000;
    }
    
  3. 还有一个主类:

    @SpringBootApplication
    @EnableDiscoveryClient
    public class ProviderApplication {
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class, args);
        }
    }
    
  4. 配置文件如下:

    spring: 
      application: 
        name: spring-cloud-server
    
    server: 
      port: 9003
      tomcat: 
        maxThreads: 500
        uriEncoding: utf-8
    
    eureka:  
      instance: 
        preferIpAddress: true
        instanceId: ${spring.cloud.client.ipAddress}:${server.port}
      client: 
        serviceUrl: 
           defaultZone: http://eureka3:8000/eureka/,http://eureka:8000/eureka/,http://eureka2:8000/eureka/
    
  5. 启动两台机器提供服务,启动脚本如下:

    nohup /data/cloud/jdk/bin/java -server -Xmx4g -Xms4g -Xss256k -XX:+UseG1GC -XX:+PrintGCDateStamps -Xloggc:/data/cloud/gc.log -jar /data/cloud/provider-test.jar > /data/cloud/stdout.log &
    

三、增加consumer-test实现

  1. pom如下:

    <parent>
        <groupId>com.sohu.tv</groupId>
        <artifactId>spring-cloud-test</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    
    <artifactId>consumer-test</artifactId>
    <packaging>jar</packaging>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
    </dependencies>
    
  2. 代码如下:

    1 启动类:
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    public class ConsumerApplication {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class, args);
        }
    }
    
    2 feign 服务
    @FeignClient(name = "spring-cloud-server"/**)
    public interface ConsumerService {
        @RequestMapping("/hello10")
        public String hello10();
         
        @RequestMapping("/hello100")
        public String hello100();
         
        @RequestMapping("/hello1000")
        public String hello1000();
    }
    
    3 对外的rest接口
    @RestController
    public class ConsumerController {
        @Autowired
        ConsumerService consumerService;
         
        @RequestMapping("/hello10")
        public String hello10() {
            return consumerService.hello10();
        }
         
        @RequestMapping("/hello100")
        public String hello100() {
            return consumerService.hello100();
        }
         
        @RequestMapping("/hello1000")
        public String hello1000() {
            return consumerService.hello1000();
        }
    }
    
  3. 配置文件如下:

    spring: 
      application:
        name: spring-cloud-consumer
    
    server:
      port: 9001
      tomcat: 
        maxThreads: 1000
        uriEncoding: utf-8
    
    eureka:
      instance:
        preferIpAddress: true
        instanceId: ${spring.cloud.client.ipAddress}:${server.port}
      client:
        serviceUrl:
          defaultZone: http://eureka3:8000/eureka/,http://eureka:8000/eureka/,http://eureka2:8000/eureka/
    
    feign:
      hystrix: 
        enabled: false     
    
    spring-cloud-server: 
      ribbon: 
        MaxAutoRetries: 1
        ConnectTimeout: 2000
        ReadTimeout: 1000
        OkToRetryOnAllOperations: false
        EnableGZIPContentEncodingFilter: true
    
  4. 启动脚本:

    nohup /opt/cloud/jdk/bin/java -server -Xmx4g -Xms4g -Xss256k -XX:+UseG1GC -XX:+PrintGCDateStamps -Xloggc:/opt/cloud/gc.log -jar /opt/cloud/consumer-test.jar > /opt/cloud/stdout.log &
    

四、feign性能测试

为了测试不同的http客户端的表现,并未增加hystrix的支持,consumer的链接超时为2秒,读取超时为1秒,另外,每次测试都经过了预热,只测试小数据传输

  1. 为consumer增加client依赖

    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-httpclient</artifactId>
    </dependency>
    或
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-okhttp</artifactId>
    </dependency>
    或什么都不依赖,采用jdk的URLConnection
    

    进行性能压测,并发3000,压测10万次,采用长链,分别压测3个接口:

    ab -k -n 100000 -c 3000 http://127.0.0.1:9001/hello10

    ab -k -n 100000 -c 3000 http://127.0.0.1:9001/hello100

    ab -k -n 100000 -c 3000 http://127.0.0.1:9001/hello1000

  2. 机器配置如下:

    cpu核数主频
    consumer-test162.40GHz
    provider-test162.27GHz
  3. 具体数据如下(并发3000,压测10万次表现如下(压测3次以上,取最好表现)):

    client10个字符100个字符1000个字符
    吞吐量响应时间中位值吞吐量响应时间中位值吞吐量响应时间中位值
    httpclient3542846ms3526850ms3427875ms
    okhttp14389208ms13782217ms13761218ms
    JDK URLConnection13728218ms13577220ms13800217ms

五、resttemplate性能测试

  1. consumer采用resttemplate作为测试,代码比较简单,如下:

    1 默认实现 - 采用jdk的HttpURLConnection
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate(f);
    }
    
    2 采用okhttp3
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        OkHttp3ClientHttpRequestFactory f  =new OkHttp3ClientHttpRequestFactory();
        f.setConnectTimeout(2000);
        f.setReadTimeout(1000);
        f.setWriteTimeout(1000);
        return new RestTemplate(f);
    }
    
    3 采用httpclient 4.3
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {        
        HttpComponentsClientHttpRequestFactory f = new HttpComponentsClientHttpRequestFactory();
        f.setConnectTimeout(2000);
        f.setReadTimeout(1000);
        return new RestTemplate(f);
    }
    
  2. 压测表现如下:(并发3000,压测10万次表现如下(压测3次以上,取最好表现)):

    client10个字符100个字符1000个字符
    吞吐量响应时间中位值吞吐量响应时间中位值吞吐量响应时间中位值
    httpclient6058495ms6051495ms6021498ms
    okhttp16134185ms16194185ms15885188ms
    JDK URLConnection16009187ms15695191ms15172197ms

六、结论

从压测数据表现来看,性能上resttemplate整体上更胜一筹(可能由于feign采用了动态代理和反射机制)。

在各个http客户端默认配置下,okhttp3性能更好一些。

从代码优雅角度来讲,feign更简洁,易懂。

测试结果依赖于测试的环境和数据,及依赖的软硬件版本和性能,不代表所有情况!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值