1. 程式人生 > 其它 >今天寫了一個可以測試併發數和執行次數的壓力測試程式碼。(Java)

今天寫了一個可以測試併發數和執行次數的壓力測試程式碼。(Java)

 

前言

現在的開發基本上都是前後端分離,前後端互動都是通過API文件。有了API文件大家各自開發,互不干擾。

1、傳統方式

傳統方式是文件設計好之後,分別發給前端和後端人員。這樣有個缺點,介面資訊一旦變化,文件就需要重新發送給前後端人員。無法做到實時。所以浪費時間和精力。

2、swagger方式

我們的後臺應用集成了swagger之後,會自動暴露出我們的介面,而且這個介面形式還是通過restful風格釋出的。一旦後端的介面有變化,會立刻顯示出來,因此極大地提高了效率。

OK,基本上一句話就可以總結他的好處,那就是後端寫的api文件可以通過swagger的形式實時的釋出出來,供前端人員檢視。

3、其他方式

swagger的頁面說實話長得不好看,也有一些其他的方案,不是有很多bug,就是收費。目前swagger是使用的最多的。我目前也正在做這個樣的開源專案,基於swagger做出類似於其他方案的頁面,而且功能更加的強大。

一、程式碼整合

前提條件是要新建一個springboot專案。這點就不演示了。

第一步:新增依賴

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>
2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>

2.9.2的版本是用的最多的,具體的可以直接去maven的官網去搜索,找一個使用量最多的版本即可。

第二步:配置

新建config包,建立SwaggerConfig類

@EnableSwagger2
@Configuration
public class Swagger2Config {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
             .apiInfo(apiInfo())
             .select()
             //為當前包路徑,控制器類包
             .apis(RequestHandlerSelectors.basePackage("com.fdd.controller"))
            .paths(PathSelectors.any())
             .build();
    }
    //構建 api文件的詳細資訊函式
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
            //頁面標題
           .title("XX平臺API介面文件")
            //建立人
           .contact(new Contact("馮鼕鼕", "http://www.javachat.cc",  
                 "[email protected]"))
           //版本號
          .version("1.0")
           //描述
          .description("系統API描述")
          .build();
    }

這裡的配置也比較簡單。這裡有很多選項供我們去配置。如果我們的專案有多個組,只需要建立多個Docket即可。這時候掃描的包換成每個組的包路徑。

第三步:controller類中配置

新建一個controller包,然後建立HelloController類

@Api("Hello控制類")
@RestController 
public class HelloController {
    @GetMapping(value = "/user")
    public User getUser(){
        return new User("愚公要移山","123456");
    }
    @ApiOperation("可以指定引數的API")
    @PostMapping("/param")
    public String hello2(@ApiParam("使用者名稱") String name){
        return "hello" + name;
    }
}

這裡我們可以看出,使用註解就可以對這個類、方法、欄位等等進行解釋說明。其他的欄位還有很多,在使用的時候會有相應的提示,可以自己試一遍:

第四步:檢視效果

訪問:127.0.0.1:8080/swagger-即可。

這裡就是最終的展示效果。OK,到這一步基本上就整合進來了。下面說一下可能會遇到的配置。

三、常見其他問題

1、Spring Security - 配置免認證訪問

有時候我們的Springboot集成了SpringSecurity,這時候如果訪問swagger的地址會自動跳轉到登入頁面。這是因為SpringSecurity對其進行了攔截。為此我們只需要在我們的SpringSecurity配置一下進行放行即可。

現在配置一下,進行放行。在config包下新建一個SpringSecurityConfig類

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/swagger-ui.html").permitAll()
                .antMatchers("/webjars/**").permitAll()
                .antMatchers("/swagger-resources/**").permitAll()
                .antMatchers("/v2/*").permitAll()
                .antMatchers("/csrf").permitAll()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
        ;
    }
}

此時就可以正常的訪問了。

2、為swagger設定jwt

這種方式比較簡單,只需要一步即可。修改我們的swaggerConfig類即可。

@EnableSwagger2
@Configuration
public class Swagger2Config {
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .securityContexts(Arrays.asList(securityContext()))
                .securitySchemes(Arrays.asList(apiKey()))
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }
    //構建 api文件的詳細資訊函式
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                //頁面標題
                .title("XX平臺API介面文件")
                //建立人
                .contact(new Contact("馮鼕鼕", "http://www.javachat.cc",
                        "[email protected]"))
                //版本號
                .version("1.0")
                //描述
                .description("系統API描述")
                .build();
    }
    private ApiKey apiKey() {
        return new ApiKey("JWT", "Authorization", "header");
    }
    private SecurityContext securityContext() {
        return SecurityContext.builder().securityReferences(defaultAuth()).build();
    }
<span class="kd" style="font-weight: 600;">private</span> <span class="n">List</span><span class="o" style="font-weight: 600;">&lt;</span><span class="n">SecurityReference</span><span class="o" style="font-weight: 600;">&gt;</span> <span class="nf" style="font-weight: 600; color: #f1403c;">defaultAuth</span><span class="o" style="font-weight: 600;">()</span> <span class="o" style="font-weight: 600;">{</span>
    <span class="n">AuthorizationScope</span> <span class="n">authorizationScope</span> 
     <span class="o" style="font-weight: 600;">=</span> <span class="k" style="font-weight: 600;">new</span> <span class="n">AuthorizationScope</span><span class="o" style="font-weight: 600;">(</span><span class="s" style="color: #f1403c;">"global"</span><span class="o" style="font-weight: 600;">,</span> <span class="s" style="color: #f1403c;">"accessEverything"</span><span class="o" style="font-weight: 600;">);</span>
    <span class="n">AuthorizationScope</span><span class="o" style="font-weight: 600;">[]</span> <span class="n">authorizationScopes</span> <span class="o" style="font-weight: 600;">=</span> <span class="k" style="font-weight: 600;">new</span> <span class="n">AuthorizationScope</span><span class="o" style="font-weight: 600;">[</span><span class="n">1</span><span class="o" style="font-weight: 600;">];</span>
    <span class="n">authorizationScopes</span><span class="o" style="font-weight: 600;">[</span><span class="n">0</span><span class="o" style="font-weight: 600;">]</span> <span class="o" style="font-weight: 600;">=</span> <span class="n">authorizationScope</span><span class="o" style="font-weight: 600;">;</span>
    <span class="k" style="font-weight: 600;">return</span> <span class="n">Arrays</span><span class="o" style="font-weight: 600;">.</span><span class="na" style="color: #0066ff;">asList</span><span class="o" style="font-weight: 600;">(</span><span class="k" style="font-weight: 600;">new</span> <span class="n">SecurityReference</span><span class="o" style="font-weight: 600;">(</span><span class="s" style="color: #f1403c;">"JWT"</span><span class="o" style="font-weight: 600;">,</span> <span class="n">authorizationScopes</span><span class="o" style="font-weight: 600;">));</span>
<span class="o" style="font-weight: 600;">}</span>

}

加了一些token驗證的程式碼,比較簡單,關於JWT的東西,可以私下了解。這裡不贅述了。

3、隱藏Endpoint

有時候自己寫的controller,或者是controller裡面的介面方法不想讓前端人員看到,我們可以隱藏即可。

第一:隱藏整個controller

@ApiIgnore
@RestController
public class MyController {
    //方法
}

第二:隱藏某個介面方法1

@ApiIgnore
@ApiOperation(value = "描述資訊")
@GetMapping("/getAuthor")
public String getAuthor() {
    return "愚公要移山";
}

第三:隱藏某個介面方法2

@ApiOperation(value = "描述資訊", hidden = true)
@GetMapping("/get")
public LocalDate getDate() {
    return LocalDate.now();
}

原文地址:https://zhuanlan.zhihu.com/p/344759568