通用工具封装¶
restTemplate封装
package org.example.config;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
* @author dkw
* RestTemplate bean,访问 RESTful 服务的客户端工具
* RestTemplate性能低,通过连接池复用连接,减少 TCP 握手和 SSL 开销,提升请求响应速度。
*/
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory requestFactory){
return new RestTemplate(requestFactory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
return new HttpComponentsClientHttpRequestFactory(httpClient());
// SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
// factory.setReadTimeout(1000);
// factory.setConnectTimeout(1000);
// return factory;
}
@Bean
public HttpClient httpClient(){
// 1. 注册HTTP和HTTPS协议的Socket工厂
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", SSLConnectionSocketFactory.getSocketFactory())
.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
// 连接池最大是500个连接
connectionManager.setMaxTotal(500);
// MaxPerRoute是对maxtotal的细分,每个主机的并发最大是300,route是指域名
connectionManager.setDefaultMaxPerRoute(300);
RequestConfig requestConfig = RequestConfig.custom()
// 返回数据的超时时间
.setSocketTimeout(20000)
// 连接上服务器的超时时间
.setConnectTimeout(10000)
// 从连接池中获取连接的超时时间
.setConnectionRequestTimeout(1000)
.build();
CloseableHttpClient closeableHttpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig)
.setConnectionManager(connectionManager)
.build();
return closeableHttpClient;
}
}
线程池配置:线程池配置和上面的http连接池配置都适用于提高qps
package org.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 线程池配置
*/
@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {
@Bean("threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
// 设置核心线程数,线程池维护线程的最少数量,即使没有任务需要执行,也会一直存在
threadPoolTaskExecutor.setCorePoolSize(8);
// 阻塞队列的最大值,核心线程满时,可创建的阻塞线程的最大值
threadPoolTaskExecutor.setQueueCapacity(1024);
// 最大线程池数量,当线程数>=CorePoolSize,且任务队列已满时,线程池会创建出新线程来处理任务
// 任务队列已满时,且当线程数 = MaxPoolSize,线程池会拒绝处理任务而抛出异常
threadPoolTaskExecutor.setMaxPoolSize(64);
// 线程的存活时长,当线程空闲时,允许现成的空闲时间最长为30s,超过30s就会自动销毁
threadPoolTaskExecutor.setKeepAliveSeconds(30);
threadPoolTaskExecutor.setThreadNamePrefix("自定义线程池");
//拒绝策略
// CallerRunsPolicy:由调用者线程处理任务(适用于不允许丢失任务的场景)。
// DiscardOldestPolicy:丢弃队列中最旧的任务,尝试处理新任务(适用于允许部分任务超时的场景)。
// DiscardPolicy:静默丢弃任务(谨慎使用,可能导致数据丢失)。
//AbortPolicy,线程池的默认策略,会直接丢掉任务并且抛出RejectExecutionException异常
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
// 初始化线程池(必须调用,否则配置不生效)
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
redisconfig配置,进行序列化和反序列化配置的时候注意,别踩坑。简单的字符串可以直接使用StringRedisTemplate。
package org.example.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisTemplateConfiguration {
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
// RedisConnectionFactory:连接工厂,由 Spring 自动配置(如 Lettuce 或 Jedis 实现),用于创建 Redis 连接。
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//配置序列化规则,Jackson2JsonRedisSerializer:将 Value 序列化为 JSON 格式,支持复杂对象的序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
// 允许序列化/反序列化所有属性(包括私有字段)
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
//设置key-value序列化规则,Redis 存储数据时需将对象序列化为字节数组,代码中配置了两种序列化方式:
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
//设置hash-value序列化规则
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
return redisTemplate;
}
}