1. 多线程并发使用okhttp时要复用一个OkHttpClient实例
  2. 多线程并发执行的线程数要和OkHttpClient的池数量相同才不会导致执行异常
package com.yh.proxy.pay.util;

import com.yh.proxy.basic.utils.RandomDataUtils;
import lombok.SneakyThrows;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**java 模拟测试多线程访问http请求
 * @author wdh
 *
 */

public class ServiceThreadTest2 implements Runnable {

    private String url;

    private String authUser;
    private String authPassword;
    private String proxyHost;
    private Integer port;
    private List<String> list;
    private OkHttpClient okHttpClient;

    public String getAuthUser() {
        return authUser;
    }

    public void setAuthUser(String authUser) {
        this.authUser = authUser;
    }

    public String getAuthPassword() {
        return authPassword;
    }

    public void setAuthPassword(String authPassword) {
        this.authPassword = authPassword;
    }

    public String getProxyHost() {
        return proxyHost;
    }

    public void setProxyHost(String proxyHost) {
        this.proxyHost = proxyHost;
    }

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }


    public OkHttpClient getOkHttpClient() {
        return okHttpClient;
    }

    public void setOkHttpClient(OkHttpClient okHttpClient) {
        this.okHttpClient = okHttpClient;
    }


    public ServiceThreadTest2(String url, String authUser, String authPassword, String proxyHost, Integer port, List<String> list, OkHttpClient client) {
        super();
        this.url = url;
        this.authUser = authUser;
        this.authPassword = authPassword;
        this.proxyHost = proxyHost;
        this.port = port;
        this.list = list;
        this.okHttpClient = client;
    }


    public String getUrl() {
        return url;
    }


    public void setUrl(String url) {
        this.url = url;
    }

//    @Bean
    public static X509TrustManager x509TrustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            }
            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };
    }
//    @Bean
    public static SSLSocketFactory sslSocketFactory() {
        try {
            //信任任何链接
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return null;
    }


//    @Bean
    public static ConnectionPool pool() {
        return new ConnectionPool(500, 50, TimeUnit.MINUTES);
    }

    public static OkHttpClient okHttpClient(){
        return new OkHttpClient().newBuilder()
                .retryOnConnectionFailure(true)//容错 重连打开
                .sslSocketFactory(sslSocketFactory(), x509TrustManager())
                .connectionPool(pool())
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60,TimeUnit.SECONDS)
                .writeTimeout(60,TimeUnit.SECONDS)
                .build();
    }
    @SneakyThrows
    @Override
    public void run() {
        String qiehuanIp = "https://s.hideproxy.net/index/lk?user="+authUser+"&pass="+authPassword;
//        OkHttpClient client = okHttpClient();
        Request request = new Request.Builder()
//                .addHeader("Connection","close")//关闭长连接
                .url(qiehuanIp)
                .method("GET", null)
                .build();
        Response response = okHttpClient.newCall(request).execute();
        if(response.code() == 204){
            String upstream = response.header("Upstream");
            System.out.println(Thread.currentThread().getName()+ " 当前子账号是: "+authUser+" 请求接口成功 请求头内容为: "+upstream);

        }
        if(response.code() != 204){
            System.err.println("当前子账号是: "+authUser+" 请求接口未成功 "+response.body().string());

        }
    }

    public static void main(String[] args) throws IOException {

        Object o = new Object();
        //运用java工具类中线程池
        OkHttpClient client = okHttpClient();
        List<String> list = new ArrayList<>();
        ExecutorService pool = Executors.newFixedThreadPool(500);//指定数量线程
//        ExecutorService pool = Executors.newCachedThreadPool();
        while (true) {
            synchronized (o) {//加锁
//        for (int i = 0; i < 10; i++) {
                String url = "https://api.live.bilibili.com/client/v1/Ip/getInfoNew";
                Integer randomData = RandomDataUtils.getRandomData(1, 500);
                String authUser = "huangkun1zz-" + randomData;//死循环随机子账号
//            String authUser = "huangkun1zz-" + i;//for循环子账号
                String authPassword = "52B4EG20";
                String proxyHost = "gate.hide-proxy.pro";
                Integer port = 1234;

                pool.execute(new ServiceThreadTest2(url, authUser, authPassword, proxyHost, port, list,client));
            }
        }
    }


}


上一篇 下一篇