Commit d92e6fae authored by lihaipeng's avatar lihaipeng

RedisListener

parent 5b01dc64
......@@ -36,4 +36,22 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<configuration>
<attach>true</attach>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
......@@ -28,4 +28,7 @@ public interface UserApi {
@PostMapping(value = "/user/add", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
Boolean add(@RequestBody User user);
@ApiOperation(value = "用户详情")
@PostMapping(value = "/getUser", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
User getUser(@RequestBody User user);
}
......@@ -17,6 +17,21 @@
<artifactId>unififi-demo-api</artifactId>
<version>${unififi-api.version}</version>
</dependency>
<dependency>
<groupId>com.u2c</groupId>
<artifactId>u2c-basic-dto</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.u2c</groupId>
<artifactId>u2c-scheduler-dto</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.unififi</groupId>
<artifactId>unififi-core</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
......
......@@ -10,9 +10,9 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
@SpringBootApplication(scanBasePackages = {"com.u2c", "com.unififi"})
@EnableDiscoveryClient
@EnableFeignClients
@EnableFeignClients(basePackages = {"com.u2c", "com.unififi"})
public class Demo1Application {
private static final Logger logger = LoggerFactory.getLogger(Demo1Application.class);
......
package com.unififi.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
@Configuration
@RefreshScope
@ConfigurationProperties(ignoreInvalidFields = true, prefix = UnififiProperties.PREFIX)
public class UnififiProperties {
public static final String PREFIX = "unififi";
private Logger logger = new Logger();
private Header header = new Header();
private String controllerPointcut = "execution(* com.*.controller.*.*(..))";
private String servicePointcut = "execution(* com.u2c.service..*.*(..))";
public Logger getLogger() {
return logger;
}
public void setLogger(Logger logger) {
this.logger = logger;
}
public Header getHeader() {
return header;
}
public void setHeader(Header header) {
this.header = header;
}
public String getControllerPointcut() {
return controllerPointcut;
}
public void setControllerPointcut(String controllerPointcut) {
this.controllerPointcut = controllerPointcut;
}
public String getServicePointcut() {
return servicePointcut;
}
public void setServicePointcut(String servicePointcut) {
this.servicePointcut = servicePointcut;
}
public static class Logger {
private Setting feign = new Setting();
private Setting rest = new Setting();
private Setting controller = new Setting();
public Setting getFeign() {
return feign;
}
public void setFeign(Setting feign) {
this.feign = feign;
}
public Setting getRest() {
return rest;
}
public void setRest(Setting rest) {
this.rest = rest;
}
public Setting getController() {
return controller;
}
public void setController(Setting controller) {
this.controller = controller;
}
}
public static class Header {
private List<String> throughNames = new ArrayList<>();
public List<String> getThroughNames() {
return throughNames;
}
public void setThroughNames(List<String> throughNames) {
this.throughNames = throughNames;
}
}
public static class Setting {
private boolean enabled = true;
private List<String> ignoreResponseDataMethodSigns = new ArrayList<>();
private List<String> skipMethodSigns = new ArrayList<>();
private boolean showSpendms = false;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public List<String> getIgnoreResponseDataMethodSigns() {
return ignoreResponseDataMethodSigns;
}
public void setIgnoreResponseDataMethodSigns(List<String> ignoreResponseDataMethodSigns) {
this.ignoreResponseDataMethodSigns = ignoreResponseDataMethodSigns;
}
public List<String> getSkipMethodSigns() {
return skipMethodSigns;
}
public void setSkipMethodSigns(List<String> skipMethodSigns) {
this.skipMethodSigns = skipMethodSigns;
}
public boolean isShowSpendms() {
return showSpendms;
}
public void setShowSpendms(boolean showSpendms) {
this.showSpendms = showSpendms;
}
}
}
package com.unififi.config.advice;
import com.unififi.config.UnififiProperties;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AdviceConfig {
@Bean
@ConditionalOnMissingBean(UnififiProperties.class)
UnififiProperties unififiProperties() {
return new UnififiProperties();
}
@Bean(value = "controllerLogAdvice")
public AspectJExpressionPointcutAdvisor controllerLogAdvice(UnififiProperties unififiProperties) {
AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
advisor.setExpression(unififiProperties.getControllerPointcut());
advisor.setAdvice(new ControllerLogAdvice(unififiProperties));
return advisor;
}
@Bean(value = "serviceExceptionAdvice")
public AspectJExpressionPointcutAdvisor serviceExceptionAdvice(UnififiProperties unififiProperties) {
AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
advisor.setExpression("execution(* com.*.service..*.*(..))");
advisor.setAdvice(new ServiceExceptionAdvice(unififiProperties));
return advisor;
}
}
package com.unififi.config.advice;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
/**
* 统一异常处理
*/
@Slf4j
@RestControllerAdvice
public class ControllerExceptionHandler {
@ExceptionHandler(Exception.class)
public Map handleException(Exception e) {
Map map = new HashMap();
map.put("code", 500);
map.put("msg", "系统错误");
log.error("Exception: ", e);
return map;
}
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public Map handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
Map map = new HashMap();
map.put("code", 501);
map.put("msg", "方法不支持");
log.error("HttpRequestMethodNotSupportedException: ", e);
return map;
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
Map map = new HashMap();
map.put("code", 502);
map.put("msg", "参数错误");
log.error("MethodArgumentNotValidException: ", e);
return map;
}
}
package com.unififi.config.advice;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.unififi.config.UnififiProperties;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
public class ControllerLogAdvice implements MethodInterceptor {
private final static Logger logger = LoggerFactory.getLogger("ControllerLog");
private UnififiProperties unififiProperties;
public ControllerLogAdvice(UnififiProperties unififiProperties) {
this.unififiProperties = unififiProperties;
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String sortMethodName = getSortMethodName(invocation.getMethod());
try {
long start = System.nanoTime();
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
String requestData = null;
if ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) {
requestData = JSONArray.toJSONString(invocation.getArguments());
} else if ("GET".equalsIgnoreCase(request.getMethod())) {
requestData = request.getQueryString();
}
if (logger.isInfoEnabled() && unififiProperties.getLogger().getController().isEnabled()) {
if (!unififiProperties.getLogger().getController().getSkipMethodSigns().contains(sortMethodName)) {
logger.info("UNIFIFI-REQ-[{}] {}", sortMethodName, (requestData != null ? requestData : ""));
}
}
Object result = invocation.proceed();
long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
String responseData = null;
if (result != null) {
responseData = JSON.toJSONString(result);
}
if (logger.isInfoEnabled() && unififiProperties.getLogger().getController().isEnabled()) {
if (!unififiProperties.getLogger().getController().getSkipMethodSigns().contains(sortMethodName)) {
if (unififiProperties.getLogger().getController().getIgnoreResponseDataMethodSigns().contains(sortMethodName)) {
logger.info("UNIFIFI-RESP-[{}] IGNORE_DATA size:{} spend:{}ms", sortMethodName, (responseData != null ? responseData.length() : 0), elapsedTime);
} else {
logger.info("UNIFIFI-RESP-[{}] {} size:{} spend:{}ms", sortMethodName, (responseData != null ? responseData : ""), (responseData != null ? responseData.length() : 0), elapsedTime);
}
}
}
return result;
} catch (Throwable throwable) {
if (logger.isErrorEnabled() && unififiProperties.getLogger().getController().isEnabled()) {
logger.error("UNIFIFI-RESP-[{}] [{}]{}", sortMethodName, throwable.getClass().getSimpleName(), throwable.getMessage());
}
return throwable;
}
}
private String getSortMethodName(Method method) {
StringBuilder sb = new StringBuilder();
appendType(sb, method.getDeclaringClass(), false);
sb.append(".");
sb.append(method.getName());
sb.append("(");
Class<?>[] parametersTypes = method.getParameterTypes();
appendTypes(sb, parametersTypes, false, false);
sb.append(")");
return sb.toString();
}
private void appendTypes(StringBuilder sb, Class<?>[] types, boolean includeArgs,
boolean useLongReturnAndArgumentTypeName) {
if (includeArgs) {
for (int size = types.length, i = 0; i < size; i++) {
appendType(sb, types[i], useLongReturnAndArgumentTypeName);
if (i < size - 1) {
sb.append(",");
}
}
} else {
if (types.length != 0) {
sb.append("..");
}
}
}
private void appendType(StringBuilder sb, Class<?> type, boolean useLongTypeName) {
if (type.isArray()) {
appendType(sb, type.getComponentType(), useLongTypeName);
sb.append("[]");
} else {
sb.append(useLongTypeName ? type.getName() : type.getSimpleName());
}
}
}
package com.unififi.config.advice;
import com.unififi.config.UnififiProperties;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
public class ServiceExceptionAdvice implements MethodInterceptor {
private final static Logger logger = LoggerFactory.getLogger(ServiceExceptionAdvice.class);
private UnififiProperties unififiProperties;
public ServiceExceptionAdvice(UnififiProperties unififiProperties) {
this.unififiProperties = unififiProperties;
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
return invocation.proceed();
} catch (Throwable throwable) {
logger.error("ServiceException: ", throwable);
Map map = new HashMap();
map.put("code", 500);
map.put("msg", "系统错误");
return map;
}
}
}
package com.unififi.config.converter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.google.common.base.Charsets;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class HttpMessageConverterConfig {
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters(FastJsonHttpMessageConverter fastJsonHttpMessageConverter) {
return new HttpMessageConverters(fastJsonHttpMessageConverter);
}
@Bean
public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
SerializerFeature[] serializerFeatures = new SerializerFeature[]{
// Date的日期转换器
SerializerFeature.WriteDateUseDateFormat,
// 循环引用
SerializerFeature.DisableCircularReferenceDetect
};
fastJsonConfig.setSerializerFeatures(serializerFeatures);
fastJsonConfig.setCharset(Charsets.UTF_8);
fastConverter.setFastJsonConfig(fastJsonConfig);
List<MediaType> fastjsonSupportedMediaTypes = new ArrayList<>();
fastjsonSupportedMediaTypes.add(MediaType.TEXT_PLAIN);
fastjsonSupportedMediaTypes.add(MediaType.APPLICATION_JSON);
fastConverter.setSupportedMediaTypes(fastjsonSupportedMediaTypes);
return fastConverter;
}
}
package com.unififi.config.feign;
import com.unififi.config.UnififiProperties;
import feign.Logger;
import feign.RequestInterceptor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.openfeign.FeignLoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Configuration
public class FeignConfig {
@Autowired
private UnififiProperties unififiProperties;
@Bean
@ConditionalOnMissingBean(UnififiProperties.class)
UnififiProperties loggerConfig() {
return new UnififiProperties();
}
@Bean
Logger.Level feignLevel() {
return Logger.Level.NONE;
}
@Bean
FeignLoggerFactory infoFeignLoggerFactory(UnififiProperties unififiProperties) {
return new UnififiFeignLoggerFactory(unififiProperties.getLogger().getFeign());
}
@Bean
public RequestInterceptor headerInterceptor() {
return requestTemplate -> {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
if (attributes == null) {
return;
}
HttpServletRequest request = attributes.getRequest();
for (String headerName : unififiProperties.getHeader().getThroughNames()) {
String token = request.getHeader(headerName);
if (StringUtils.isNotEmpty(token)) {
requestTemplate.header(headerName, token);
}
}
};
}
}
package com.unififi.config.feign;
import com.unififi.config.UnififiProperties;
import feign.Request;
import feign.Response;
import feign.Util;
import org.apache.commons.codec.Charsets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import static feign.Util.decodeOrDefault;
public class UnififiFeignLogger extends feign.Logger {
private static final Logger logger = LoggerFactory.getLogger("FeignLog");
// private final Logger logger;
private UnififiProperties.Setting setting;
public UnififiFeignLogger(Logger logger, UnififiProperties.Setting setting) {
// this.logger = logger;
this.setting = setting;
}
@Override
protected void logRequest(String configKey, Level logLevel, Request request) {
if (logger.isInfoEnabled() && setting.isEnabled()) {
if (!setting.getSkipMethodSigns().contains(configKey)) {
logger.info("FEIGN-REQ-[{}] {}-->{} {}", configKey, request.body() != null ? new String(request.body(), Charsets.UTF_8) : "", request.httpMethod(), request.url());
}
}
}
@Override
protected Response logAndRebufferResponse(String configKey, Level logLevel, Response response, long elapsedTime) throws IOException {
if (response.body() != null) {
byte[] bodyData = Util.toByteArray(response.body().asInputStream());
if (logger.isInfoEnabled() && setting.isEnabled()) {
if (!setting.getSkipMethodSigns().contains(configKey)) {
if (setting.getIgnoreResponseDataMethodSigns().contains(configKey)) {
logger.info("FEIGN-RESP-[{}] IGNORE_DATA size:{} spend:{}ms", configKey, (bodyData != null ? bodyData.length : 0), elapsedTime);
} else {
logger.info("FEIGN-RESP-[{}] {} size:{} spend:{}ms", configKey, decodeOrDefault(bodyData, Charsets.UTF_8, ""), (bodyData != null ? bodyData.length : 0), elapsedTime);
}
}
}
return response.toBuilder().body(bodyData).build();
} else {
if (logger.isInfoEnabled() && setting.isEnabled()) {
if (!setting.getSkipMethodSigns().contains(configKey)) {
logger.info("FEIGN-RESP-[{}] size:0 spend:{}ms", configKey, elapsedTime);
}
}
return response;
}
}
@Override
protected IOException logIOException(String configKey, Level logLevel, IOException ioe, long elapsedTime) {
if (logger.isErrorEnabled() && setting.isEnabled()) {
logger.error("FEIGN-RESP-[{}] [{}]{}", configKey, ioe.getClass().getSimpleName(), ioe.getMessage());
}
return ioe;
}
@Override
protected void log(String configKey, String format, Object... args) {
if (logger.isInfoEnabled()) {
logger.info(String.format(methodTag(configKey) + format, args));
}
}
}
package com.unififi.config.feign;
import com.unififi.config.UnififiProperties;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FeignLoggerFactory;
public class UnififiFeignLoggerFactory implements FeignLoggerFactory {
private UnififiProperties.Setting setting;
public UnififiFeignLoggerFactory(UnififiProperties.Setting setting) {
this.setting = setting;
}
@Override
public feign.Logger create(Class<?> type) {
return new UnififiFeignLogger(LoggerFactory.getLogger(type), this.setting);
}
}
......@@ -35,4 +35,5 @@ public class RedisConfig {
return template;
}
}
\ No newline at end of file
package com.unififi.config.rest;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.google.common.base.Charsets;
import com.unififi.config.UnififiProperties;
import org.apache.http.client.HttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.util.Iterator;
import java.util.List;
@Configuration
public class RestTemplateConfig {
@Value("${ribbon.ConnectTimeout:5000}")
private Integer connectTimeout;
@Value("${ribbon.ReadTimeout:60000}")
private Integer readTimeout;
@Bean
@ConditionalOnMissingBean(UnififiProperties.class)
UnififiProperties loggerConfig() {
return new UnififiProperties();
}
@Bean
public ClientHttpRequestFactory httpRequestFactory(HttpClient httpClient) {
HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
httpComponentsClientHttpRequestFactory.setConnectTimeout(this.connectTimeout);
httpComponentsClientHttpRequestFactory.setReadTimeout(this.readTimeout);
return httpComponentsClientHttpRequestFactory;
}
@Bean(value = "restTemplate")
public RestTemplate restTemplate(ClientHttpRequestFactory httpRequestFactory, UnififiProperties unififiProperties, FastJsonHttpMessageConverter fastJsonHttpMessageConverter) {
BufferingClientHttpRequestFactory bufferingClientHttpRequestFactory = new BufferingClientHttpRequestFactory(httpRequestFactory);
RestTemplate restTemplate = new RestTemplate(bufferingClientHttpRequestFactory);
restTemplate.getInterceptors().add(new RestTemplateLogInterceptor(unififiProperties.getLogger().getRest()));
//fastjson 替换 jackson
List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();
while (iterator.hasNext()) {
HttpMessageConverter<?> converter = iterator.next();
if (converter instanceof StringHttpMessageConverter) {
iterator.remove();
}
if (converter instanceof GsonHttpMessageConverter || converter instanceof MappingJackson2HttpMessageConverter) {
iterator.remove();
}
}
messageConverters.add(new StringHttpMessageConverter(Charsets.UTF_8));
messageConverters.add(fastJsonHttpMessageConverter);
return restTemplate;
}
@LoadBalanced
@Bean(value = "restTemplateRibbon")
public RestTemplate restTemplateRibbon(ClientHttpRequestFactory httpRequestFactory, UnififiProperties unififiProperties, FastJsonHttpMessageConverter fastJsonHttpMessageConverter) {
BufferingClientHttpRequestFactory bufferingClientHttpRequestFactory = new BufferingClientHttpRequestFactory(httpRequestFactory);
RestTemplate restTemplate = new RestTemplate(bufferingClientHttpRequestFactory);
restTemplate.getInterceptors().add(new RestTemplateLogInterceptor(unififiProperties.getLogger().getRest()));
//fastjson 替换 jackson
List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();
while (iterator.hasNext()) {
HttpMessageConverter<?> converter = iterator.next();
if (converter instanceof StringHttpMessageConverter) {
iterator.remove();
}
if (converter instanceof GsonHttpMessageConverter || converter instanceof MappingJackson2HttpMessageConverter) {
iterator.remove();
}
}
messageConverters.add(new StringHttpMessageConverter(Charsets.UTF_8));
messageConverters.add(fastJsonHttpMessageConverter);
return restTemplate;
}
}
package com.unififi.config.rest;
import com.unififi.config.UnififiProperties;
import org.apache.commons.codec.Charsets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.concurrent.TimeUnit;
public class RestTemplateLogInterceptor implements ClientHttpRequestInterceptor {
private static final Logger logger = LoggerFactory.getLogger("RestTemplateLog");
private UnififiProperties.Setting setting;
public RestTemplateLogInterceptor(UnififiProperties.Setting setting) {
this.setting = setting;
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
String methodTag = getMethodTag(request.getURI());
if (logger.isInfoEnabled() && setting.isEnabled()) {
if (!setting.getSkipMethodSigns().contains(methodTag)) {
logger.info("REST-REQ-[{}] {}-->{} {}", methodTag, body != null ? new String(body, Charsets.UTF_8) : "", request.getMethod(), request.getURI());
}
}
long start = System.nanoTime();
ClientHttpResponse response = null;
try {
response = execution.execute(request, body);
long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
if (logger.isInfoEnabled()) {
StringBuilder inputStringBuilder = new StringBuilder();
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), Charsets.UTF_8))) {
String line = bufferedReader.readLine();
while (line != null) {
inputStringBuilder.append(line);
line = bufferedReader.readLine();
if (line != null) {
inputStringBuilder.append('\n');
}
}
}
if (logger.isInfoEnabled() && setting.isEnabled()) {
if (!setting.getSkipMethodSigns().contains(methodTag)) {
if (setting.getIgnoreResponseDataMethodSigns().contains(methodTag)) {
logger.info("REST-RESP-[{}] IGNORE_DATA size:{} spend:{}ms", methodTag, inputStringBuilder.length(), elapsedTime);
} else {
logger.info("REST-RESP-[{}] {} size:{} spend:{}ms", methodTag, inputStringBuilder.toString(), inputStringBuilder.length(), elapsedTime);
}
}
}
}
} catch (IOException ioe) {
if (logger.isErrorEnabled() && setting.isEnabled()) {
logger.error("REST-RESP-[{}] [{}]{}", methodTag, ioe.getClass().getSimpleName(), ioe.getMessage());
}
throw ioe;
}
return response;
}
private String getMethodTag(URI uri) {
try {
if (uri.getPath().indexOf('?') > -1) {
return uri.getHost() + uri.getPath().substring(0, uri.getPath().indexOf('?'));
} else {
return uri.getHost() + uri.getPath();
}
} catch (Exception e) {
return uri.getHost() + uri.getPath();
}
}
}
package com.unififi.config.ribbon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.listener.RetryListenerSupport;
public class RetryLogListener extends RetryListenerSupport {
private static final Logger logger = LoggerFactory.getLogger("RibbonRetryLog");
@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
LoadBalancedRetryContext loadBalancedRetryContext = (LoadBalancedRetryContext) context;
logger.warn("UNIFIFI-RETRY serviceId:{} count:{} exhausted:{} msg:{}", (loadBalancedRetryContext.getServiceInstance() != null ? loadBalancedRetryContext.getServiceInstance().getServiceId() : null), context.getRetryCount(), context.isExhaustedOnly(), throwable.getMessage());
}
}
package com.unififi.config.ribbon;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RibbonConfig {
@Bean
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
public LoadBalancedRetryFactory loadBalancedRetryPolicyFactory(
final SpringClientFactory clientFactory) {
return new UnififiRibbonLoadBalancedRetryFactory(clientFactory);
}
}
package com.unififi.config.ribbon;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryFactory;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.retry.RetryListener;
public class UnififiRibbonLoadBalancedRetryFactory extends RibbonLoadBalancedRetryFactory {
private RetryListener[] retryListener = {new RetryLogListener()};
public UnififiRibbonLoadBalancedRetryFactory(SpringClientFactory clientFactory) {
super(clientFactory);
}
@Override
public RetryListener[] createRetryListeners(String service) {
return retryListener;
}
}
package com.unififi.controller;
import com.alibaba.fastjson.JSON;
import com.fesf.base.BasePageReq;
import com.fesf.base.BasePageRsp;
import com.u2c.basic.client.BasicClient;
import com.u2c.basic.dto.AuthenticateRsp;
import com.u2c.scheduler.client.SchedulerLogClient;
import com.u2c.scheduler.dto.common.SchedulerLog;
import com.unififi.api.UserApi;
import com.unififi.config.AppConfig;
import com.unififi.model.TicketingOrder;
......@@ -47,6 +54,11 @@ public class Demo1Controller {
private RocketMQTemplate rocketMQTemplate;
@Autowired
private HttpServletRequest request;
@Autowired
private SchedulerLogClient schedulerLogClient;
@Autowired
private BasicClient basicClient;
@GetMapping("/echo/{string}")
public String echo(@PathVariable String string) {
......@@ -60,7 +72,7 @@ public class Demo1Controller {
@GetMapping("/user/get")
public User userGet(@RequestParam("name") String name, @RequestParam("age") Integer age) {
log.info("header. token:{}", request.getHeader("token"));
log.info("header. token:{}", request.getHeader("Authorization"));
User user = null;
user = userApi.get(name, age);
// try {
......@@ -83,6 +95,12 @@ public class Demo1Controller {
return restTemplateRibbon.getForObject("http://unififi-demo2-service/user/list", List.class);
}
@GetMapping(value = "/log/list")
public List<User> logList() {
// return userApi.list();
return restTemplateRibbon.getForObject("http://u2c-scheduler-service/log/list", List.class);
}
@GetMapping("/config/username")
public String configUsername() {
return appConfig.getUsername();
......@@ -127,4 +145,27 @@ public class Demo1Controller {
rocketMQTemplate.convertAndSend("order-push:ticketing", order);
}
@GetMapping("/sendredis")
public void sendRedis(String key) {
stringRedisTemplate.convertAndSend("topic_demo", key);
}
@PostMapping(value = "/scheduler/log/list", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public BasePageRsp<List<SchedulerLog>> schedulerLogList(@RequestBody BasePageReq<SchedulerLog> req) {
return schedulerLogClient.list(req);
}
@GetMapping("/basicAuthenticate")
public AuthenticateRsp basicAuthenticate(@RequestParam(value = "perms", required = false) String perms) {
AuthenticateRsp token = basicClient.authenticate(null, null);
log.info(JSON.toJSONString(token));
return token;
}
@PostMapping(value = "/getUser", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public User getUser(@RequestBody User user) {
log.info("demo1 getUser. name:{}", user.getName());
return userApi.getUser(user);
}
}
......@@ -10,6 +10,28 @@ server:
include: '*'
shutdown: graceful
spring:
redis:
# Redis数据库索引(默认为0)
database: 0
# host: 39.106.6.97
# port: 13350
password:
# 连接超时时间(毫秒)
timeout: 200
lettuce:
pool:
# 连接池最大连接数,默认8
max-active: 8
# 连接池中的最大空闲连接,默认8
max-idle: 8
# 连接池中的最小空闲连接,默认0
min-idle: 0
# 连接池最大阻塞等待时间,默认-1
max-wait: -1
sentinel:
master: redis1
nodes: 203.195.160.104:20202
lifecycle:
timeout-per-shutdown-phase: 60s
profiles:
......@@ -54,4 +76,5 @@ unififi:
swagger:
enable: true
\ No newline at end of file
enable: true
......@@ -57,7 +57,7 @@ public class Demo2Controller implements UserApi {
@GetMapping(value = "/user/get", produces = MediaType.APPLICATION_JSON_VALUE)
public User get(@RequestParam("name") String name, @RequestParam("age") Integer age) {
log.info("user/get. name:{}, age:{}", name, age);
log.info("header. token:{}", request.getHeader("token"));
log.info("header. token:{}", request.getHeader("Authorization"));
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
......@@ -72,4 +72,12 @@ public class Demo2Controller implements UserApi {
public String get() throws InterruptedException {
return appConfig.getUsername();
}
@Override
@PostMapping(value = "/getUser", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public User getUser(@RequestBody User user) {
log.info("demo2 getUser. name:{}", user.getName());
return userService.get(user.getName());
}
}
package com.unififi.message;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RedisListener extends MessageListenerAdapter {
@Bean
@ConditionalOnBean(MessageListenerAdapter.class)
public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter redisListener) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(redisListener, new PatternTopic("topic_config_monitor"));
return container;
}
@Override
public void onMessage(Message message, byte[] pattern) {
String channel = new String(message.getChannel());
log.info("redisListener: {} {}", channel, message.toString());
}
}
......@@ -32,7 +32,7 @@ spring:
refresh: false
group: DEFAULT_GROUP
discovery:
#ip: 39.106.6.97
#ip: 39.106.6.98
metadata:
unififi.env: ${spring.profiles.active:}
unififi.service.version: '@unififi-service.version@'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment