verysu 设计模式 设计模式 响应式编程 百度开发平台 codeforces leetcode usfca

导航

springboot

将项目放到k8s上 dockerfile编写

FROM 87b1696e3cb5
WORKDIR /app
COPY sb-business-bwprocess-1.4.0.jar /app
EXPOSE 8080
EXPOSE 9090
ENTRYPOINT ["java", "-server", "-XX:+PrintGCDetails", "-Xms6372m","-XX:MetaspaceSize=500m", "-Xmx10240m", "-Dcom.sun.management.jmxremote.port=9090", "-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.authenticate=false", "-jar", "sb-business-bwprocess-1.4.0.jar", "--server.port=8080"]

启动springboot打成jar

java -Dfile.encoding=utf-8 -jar C:\pangu-crawler-client.jar --spring.profiles.active=prod >C:\client.log

javaw -Dfile.encoding=utf-8 -jar C:\pangu-crawler-client.jar --spring.profiles.active=prod >C:\client.log
exit

修改dos命令框大小mode con cols=30 lines=20 

 杀掉进程结束后备份文件

@echo off
for /f "tokens=5" %%i in ('netstat -aon ^| findstr ":8083"') do (taskkill /f /pid %%i)
move "C:\crawler\client\pangu-crawler-client.jar" C:\crawler\client\old\pangu-crawler-client-%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%.jar
move "C:\Users\admin\pangu-crawler-client.jar" "C:\crawler\client\pangu-crawler-client.jar"
set BUILD_ID=dontKillMe

 

//配置首页访问方式
@RequestMapping("/index3")
public String test3(HttpServletRequest request){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index");
return "forward:index.html";
}

配置访问路径
@Configuration
//@ComponentScan
//@EnableWebMvc
public class DefultView extends WebMvcConfigurerAdapter {

/* @Override
public void addViewControllers(ViewControllerRegistry registry)
{
registry.addViewController("/").setViewName("forward:/index.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
super.addViewControllers(registry);

}*/

/*@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/templates/");
super.addResourceHandlers(registry);
}*/
/* @Bean

public WebMvcConfigurerAdapter getWebMvcConfigurerAdapter(){
WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter(){
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/layui.html").setViewName("login");
}
};
return adapter ;
}

@Bean
public InternalResourceViewResolver setupViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
*//**设置视图路径的前缀*//*
resolver.setPrefix("/transfer/webapp/");
*//**设置视图路径的后缀*//*
resolver.setSuffix(".html");
return resolver;

}*/

/* @Bean
public WebMvcConfigurer WebMvcConfigurer(){
WebMvcConfigurer aa = new WebMvcConfigurer(){
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/layui.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
} ;
return aa;
}*/
/* @Bean
public WebMvcConfigurationSupport WebMvcConfigurationSupport(){
WebMvcConfigurationSupport aa = new WebMvcConfigurationSupport(){
@Override
protected void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/layui.html");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/templates/");
super.addResourceHandlers(registry);
}
} ;
return aa;
}*/
}

//配置拦截器校验机制
@Configuration
//@ComponentScan
//@EnableWebMvc
public class DefultView1 implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new InterfaceAuthCheckInterceptor()).addPathPatterns("/qyc/**").excludePathPatterns("/qyc/login");
}

}
/**
* 微服务间接口访问密钥验证
* @author xiaochangwei
*
*/
class InterfaceAuthCheckInterceptor implements HandlerInterceptor {

private Logger logger = LoggerFactory.getLogger(getClass());

@Autowired
StringRedisTemplate stringRedisTemplate;

@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {

}

@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {

}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj)
throws Exception {
String key = request.getParameter("key");
if (StringUtils.isEmpty(key)) {
response.setContentType("application/json;charset=utf-8");
return false;
} else {
logger.info("test redis import :" + stringRedisTemplate.opsForValue().get(key));
// TODO 验证逻辑
return true;
}
}
}

 }
//配置访问路径
@Bean
public InternalResourceViewResolver setupViewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/static/");
resolver.setSuffix(".html");
return resolver;

}
//配置cookie校验
@Bean
public CookieExpiredChecker cookieExpiredChecker() {
return new CookieExpiredChecker() {
@Override
public boolean preCheck(ApplicationContext context, ServiceFirstArg firstArg) {
return true;
}
@Override
public boolean postCheck(ApplicationContext context, ServiceFirstArg firstArg, Object resp) {
return true;
}
};
}
需要添加的注解
@EnableAspectJAutoProxy
@EnableAsync(proxyTargetClass=true)
@EnableMongoAuditing
@EnableScheduling
//配置限定包AOP切面
@Aspect
@Component
public class Aspects implements ApplicationContextAware {

private static final Logger logger = LoggerFactory.getLogger(Aspects.class);

private ApplicationContext applicationContext;

@Autowired
private HttpManager httpManager;

@Autowired
private CookieLoader cookieLoader;

@Autowired
private CookieFreshTimer cookieFreshTimer;

@Autowired(required = false)
private CookieExpiredChecker cookieExpiredChecker;

    @Pointcut("execution(* com.pangu.crawler..*Controller.*(..)) && !execution(* com.pangu.crawler.transfer..*Controller.*(..))  ")
    private void controller() {
}

private void superTrimJsonXml(Object[] objects) {
if (objects == null) {
return;
}
for (int i = 0; i < objects.length; i++) {
if (objects[i] != null && objects[i] instanceof String) {
String s = objects[i].toString().trim();
if ((s.startsWith("{") && s.endsWith("}"))
|| (s.startsWith("[") && s.endsWith("]"))
|| (s.startsWith("<") && s.endsWith(">"))) {
objects[i] = s.replaceAll("\r|\n|\\s", "");
}
}
}
}

@Before("controller()")
public void beforeController(JoinPoint joinPoint) {
Object target = joinPoint.getTarget();
String signature = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
superTrimJsonXml(args);
String execution = String.format("%s.%s(%s)", target, signature, Arrays.toString(args));
logger.info("{} start!", execution);
}

@AfterReturning(pointcut = "controller()", returning = "result")
public void afterControllerReturn(JoinPoint joinPoint, Object result) {
if(!(result instanceof String)) {
CookieManager.clearCookies();
return;
}

Object target = joinPoint.getTarget();
String signature = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
superTrimJsonXml(args);
String execution = String.format("%s.%s(%s)", target, signature, Arrays.toString(args));
CookieManager.clearCookies();
logger.info("[{}] - clear cookies success after {} return!", result, execution);
JSONObject resultJsonObject;
try {
resultJsonObject = JSONObject.parseObject(String.valueOf(result));
} catch (Exception e) {
throw new RuntimeException("[" + execution + "] result parse object fail! result = " + result);
}
String trace = resultJsonObject.getString("trace");
if (trace == null || trace.isEmpty()) {
throw new RuntimeException("trace from [" + execution + "] result is empty! result = " + result);
}
String nsrsbh = resultJsonObject.getString("nsrsbh");
if (nsrsbh == null || nsrsbh.isEmpty()) {
throw new RuntimeException("nsrsbh from [" + execution + "] result is empty! result = " + result);
}
logger.info("{} end! result = {}", execution, result);
}

@AfterThrowing(pointcut = "controller()", throwing = "e")
public void afterControllerException(JoinPoint joinPoint, Exception e) throws Exception {
Object target = joinPoint.getTarget();
String signature = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
superTrimJsonXml(args);
String execution = String.format("%s.%s(%s)", target, signature, Arrays.toString(args));
// if (!(e instanceof PanicException)) {
// logger.error("fatal error occur!!! controller throw wrong exception type : {} when {}!!!",
// e.getClass(), execution, e);
// System.exit(-1);
// }
// PanicException panic = (PanicException) e;
// panic.setController(execution);
CookieManager.clearCookies();
logger.info("切面捕获到异常:"+execution+":",e);
// logger.info("[{}] - clear cookies success after {} throw exception!", panic.getTrace(), execution);
// logger.info("[{}] - {} throw exception!", panic.getTrace(), execution);
throw e;
}

@Around("execution(* *.*(com.pangu.crawler.framework.service.ServiceFirstArg,..))")
public Object aroundService(ProceedingJoinPoint joinPoint) throws Exception {
Object target = joinPoint.getTarget();
String signature = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
superTrimJsonXml(args);
String execution = String.format("%s.%s(%s)", target, signature, Arrays.toString(args));
// 判断第一个参数
if (args == null || args.length <= 0) {
logger.error("fatal error occur!!! service args is empty : {}", execution);
System.exit(-1);
}
Object arg = args[0];
if (!(arg instanceof ServiceFirstArg)) {
logger.error("fatal error occur!!! service first arg error : {}!!!", execution);
System.exit(-1);
}
ServiceFirstArg firstArg = (ServiceFirstArg) arg;
String trace = firstArg.getTrace();
String nsrsbh = firstArg.getNsrsbh();
CookieOperation cookieOperation = firstArg.getCookieOperation();
// 添加HttpManager对象
if (firstArg.getHttpManager() == null) {
firstArg.setHttpManager(httpManager);
}
// 输出开始日志
logger.info("[{}] - {} start!", trace, execution);
// 如果加载Cookie
if (cookieOperation == CookieOperation.LOAD) {
logger.info("[{}] - load cookies start! nsrsbh = {}", trace, nsrsbh);
Map<CookieKey, List> oldCookies = CookieManager.clearCookies();
logger.info("[{}] - local cookies clear and old cookies tobe merge before load! nsrsbh = {}, old cookies = {}",
trace, nsrsbh, oldCookies);
Map<CookieKey, List> loadCookies = cookieLoader.loadCookies(trace, nsrsbh);
if (logger.isDebugEnabled()) {
logger.debug("[{}] - loaded cookies! nsrsbh = {}, load cookies = {}", trace, nsrsbh, loadCookies);
}
if (loadCookies == null || loadCookies.isEmpty()) {
logger.info("[{}] - load cookies is empty! nsrsbh = {}", trace, nsrsbh);
throw new LoginExpiredException(trace, nsrsbh);
} else {
final Map<CookieKey, List> allCookies = new HashMap<>();
if (oldCookies != null && oldCookies.size() > 0) {
// 加载的覆盖原来的。
oldCookies.forEach(allCookies::put);
loadCookies.forEach(allCookies::put);
logger.info("[{}] - merge old cookies after load! nsrsbh = {}, all cookies = {}",
trace, nsrsbh, allCookies);
} else {
// 仅用加载的。
loadCookies.forEach(allCookies::put);
logger.info("[{}] - old cookies is empty, not merge after load! nsrsbh = {}, all cookies = {}",
trace, nsrsbh, allCookies);
}
allCookies.forEach(CookieManager::putCookie);
logger.info("[{}] - load cookies success! nsrsbh = {}", trace, nsrsbh);
}
}
// 判断Cookie是否过期
if (cookieExpiredChecker != null) {
if (firstArg.isCookieExpiredCheck()) {
if (!(target instanceof CookieExpiredCheckerMarker)) {
if (!cookieExpiredChecker.preCheck(applicationContext, ServiceFirstArg.cookie(trace, nsrsbh))) {
throw new LoginExpiredException(trace, nsrsbh);
}
}
} else {
logger.info("[{}] - do not cookie expired check! nsrsbh = {}", trace, nsrsbh);
}
} else {
logger.info("[{}] - cookie expired checker not autowired! nsrsbh = {}", trace, nsrsbh);
}
// 业务逻辑执行
Object result = null;
try {
result = joinPoint.proceed(joinPoint.getArgs());
} catch (Throwable t) {
// 输出异常日志
String errorMessage = t.getMessage();
if (t.getCause() != null) {
if (errorMessage != null && !errorMessage.trim().isEmpty()) {
errorMessage += " -> " + t.getCause().getMessage();
} else {
errorMessage = t.getCause().getMessage();
}
}
logger.error("[{}] - {} throw exception! e = {}", trace, execution, errorMessage);
if (t instanceof Exception) {
throw (Exception) t;
} else {
logger.error("fatal error occur!!!", t);
System.exit(-1);
}
}
// 判断Cookie是否过期
if (cookieExpiredChecker != null) {
if (firstArg.isCookieExpiredCheck()) {
if (!(target instanceof CookieExpiredCheckerMarker)) {
if (!cookieExpiredChecker.postCheck(applicationContext, ServiceFirstArg.cookie(trace, nsrsbh), result)) {
throw new LoginExpiredException(trace, nsrsbh);
}
}
} else {
logger.info("[{}] - do not cookie expired check! nsrsbh = {}", trace, nsrsbh);
}
} else {
logger.info("[{}] - cookie expired checker not autowired! nsrsbh = {}", trace, nsrsbh);
}
// 如果保存Cookie
if (cookieOperation == CookieOperation.SAVE) {
logger.info("[{}] - save cookies start! nsrsbh = {}", trace, nsrsbh);
Map<CookieKey, List> cookies = CookieManager.getCookieLists();
if (logger.isDebugEnabled()) {
logger.debug("[{}] - saved cookies! nsrsbh = {}, cookies = {}", trace, nsrsbh, cookies);
}
boolean saved = cookieLoader.saveCookies(trace, nsrsbh, cookies);
logger.info("[{}] - clear local cookies after save cookies! nsrsbh = {}", trace, nsrsbh);
CookieManager.clearCookies();
if (!saved) {
logger.info("[{}] - save cookies fail! nsrsbh = {}", trace, nsrsbh);
throw new Exception("save cookies failed!");
} else {
logger.info("[{}] - save cookies success! nsrsbh = {}", trace, nsrsbh);
}
}
logger.info("[{}] - add nsrsbh to cookie fresh timer! nsrsbh = {}", trace, nsrsbh);
cookieFreshTimer.addNsrsbh(nsrsbh);
// 输出结束日志
logger.info("[{}] - {} return! result = {}", trace, execution, result);
return result;
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
使用thymeleaf插件可以配置
thymeleaf:
cache: false
mode: LEGACYHTML5
check-template: true
servlet.content-type: text/html
enabled: true
encoding: UTF-8
prefix: classpath:/static/
suffix: .html
mvc:
view:
prefix: /
suffix: .html

禁止不安全的访问方式2.0以前

@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {// 1
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
collection.addMethod("HEAD");
collection.addMethod("PUT");
collection.addMethod("DELETE");
collection.addMethod("OPTIONS");
collection.addMethod("TRACE");
collection.addMethod("COPY");
collection.addMethod("SEARCH");
collection.addMethod("PROPFIND");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
}

2.0

@Bean
public ConfigurableServletWebServerFactory configurableServletWebServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addContextCustomizers(context -> {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
collection.addMethod("HEAD");
collection.addMethod("PUT");
collection.addMethod("DELETE");
collection.addMethod("OPTIONS");
collection.addMethod("TRACE");
collection.addMethod("COPY");
collection.addMethod("SEARCH");
collection.addMethod("PROPFIND");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
});
return factory;}

 spring.mvc.hiddenmethod.filter.enabled=true

server.tomcat.port-header=HEAD,PUT,DELETE,OPTIONS,TRACE,COPY,SEARCH,PROPFIN

或者在tomcat/conf/web.xml里边添加



/*
PUT
DELETE
HEAD
OPTIONS
TRACE





BASIC

--------------------------这样使得nmap curl等测试出来都是安全的

@Before("pointcut()")
public void doBefore(JoinPoint joinPoint) {
RequestAttributes attributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
// ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
// String a = "";
// if(!FORBIDDEN_METHOD.contains(request.getMethod())){
// ((HttpServletResponse) response).setStatus(HttpStatus.FORBIDDEN.value());
// return;
}
}
feign参数设置
@Bean
public Retryer feignRetryer() {
return new Retryer.Default(200, SECONDS.toMillis(2), 10);
}
/**
* 设置请求超时时间
*默认
* public Options() {
* this(10 * 1000, 60 * 1000);
* }
*/
@Bean
Request.Options feignOptions() {
return new Request.Options(60 * 1000, 60 * 1000);
}
/**
* 打印请求日志
* @return
*/
@Bean
public feign.Logger.Level multipartLoggerLevel() {
return feign.Logger.Level.FULL;
}
全局错误页面返回
public class HtmlExceptionHandler implements ErrorWebExceptionHandler {

private static final Logger log = LoggerFactory.getLogger(HtmlExceptionHandler.class);

/**
* MessageReader
*/
private List<HttpMessageReader<?>> messageReaders = Collections.emptyList();

/**
* MessageWriter
*/
private List<HttpMessageWriter<?>> messageWriters = Collections.emptyList();

/**
* ViewResolvers
*/
private List viewResolvers = Collections.emptyList();

/**
* 存储处理异常后的信息
*/
private ThreadLocal<Map<String,Object>> exceptionHandlerResult = new ThreadLocal<>();

/**
* 参考AbstractErrorWebExceptionHandler
* @param messageReaders
*/
public void setMessageReaders(List<HttpMessageReader<?>> messageReaders) {
Assert.notNull(messageReaders, "'messageReaders' must not be null");
this.messageReaders = messageReaders;
}

/**
* 参考AbstractErrorWebExceptionHandler
* @param viewResolvers
*/
public void setViewResolvers(List viewResolvers) {
this.viewResolvers = viewResolvers;
}

/**
* 参考AbstractErrorWebExceptionHandler
* @param messageWriters
*/
public void setMessageWriters(List<HttpMessageWriter<?>> messageWriters) {
Assert.notNull(messageWriters, "'messageWriters' must not be null");
this.messageWriters = messageWriters;
}

@Override
public Mono handle(ServerWebExchange exchange, Throwable ex) {
/**
* 按照异常类型进行处理
*/
HttpStatus httpStatus;
String errMsg;
if (ex instanceof NotFoundException) {
httpStatus = HttpStatus.NOT_FOUND;
errMsg = "Service Not Found." + " | " + ex.getMessage();
}else if(ex instanceof ResponseStatusException) {
ResponseStatusException responseStatusException = (ResponseStatusException) ex;
httpStatus = responseStatusException.getStatus();
errMsg = responseStatusException.getMessage();
String reason = responseStatusException.getReason();
}else{
httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
errMsg ="Internal Server Error" + " | " + ex.getMessage();
}
int httpCode = httpStatus.value();

/**
* 错误记录
*/
ServerHttpRequest request = exchange.getRequest();
String requestPath = request.getPath().value();
InetSocketAddress inetSocketAddress = request.getRemoteAddress();
String remoteAddress = inetSocketAddress.toString();
log.error("[全局异常处理]remoteAddress:{},异常请求路径:{},记录异常信息:{},QueryParams:{}",remoteAddress,request.getPath(),errMsg,request.getQueryParams());
MultiValueMap<String, String> queryParams = request.getQueryParams();
ErrorVo ev = new ErrorVo();
ev.setTime(DateUtils.getCurrDate());
ev.setHttpCode(httpCode);
ev.setMessage(errMsg);
ev.setRequestPath(requestPath);
ev.setIpPort(remoteAddress);
// ev.setParam(queryParams);
/**
* 封装响应体,此body可修改为自己的jsonBody
*/
Map<String,Object> result = new HashMap<>(2,1);
result.put("httpStatus",httpStatus);
result.put("body",ev);
/**
* 参考AbstractErrorWebExceptionHandler
*/
if (exchange.getResponse().isCommitted()) {
return Mono.error(ex);
}
exceptionHandlerResult.set(result);
ServerRequest newRequest = ServerRequest.create(exchange, this.messageReaders);
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse).route(newRequest)
.switchIfEmpty(Mono.error(ex))
.flatMap((handler) -> handler.handle(newRequest))
.flatMap((response) -> write(exchange, response));
}

/**
* 参考DefaultErrorWebExceptionHandler
* @param request
* @return
*/
protected Mono renderErrorResponse(ServerRequest request) {
Map<String,Object> result = exceptionHandlerResult.get();
ErrorVo errorVo = (ErrorVo) result.get("body");
String html = buildHtml(errorVo);
return ServerResponse.status((HttpStatus) result.get("httpStatus"))
.contentType(MediaType.TEXT_HTML)
.body(BodyInserters.fromObject(html));
}
private String buildHtml(ErrorVo errorVo){
StringBuffer sbf = new StringBuffer();
sbf.append("");
sbf.append("");
sbf.append("");
sbf.append("");
sbf.append("访问错误");
sbf.append("");
sbf.append("");
sbf.append("

服务访问错误,请稍后重试或联系管理员

");
sbf.append("
clientIp:").append(errorVo.getIpPort()).append("
");
sbf.append("
time:").append(errorVo.getTime()).append("
");
sbf.append("
code:").append(errorVo.getHttpCode()).append("
");
sbf.append("
message:").append(errorVo.getMessage()).append("
");
sbf.append("");
sbf.append("");
return sbf.toString();
}

/**
* 参考AbstractErrorWebExceptionHandler
* @param exchange
* @param response
* @return
*/
private Mono<? extends Void> write(ServerWebExchange exchange,
ServerResponse response) {
exchange.getResponse().getHeaders()
.setContentType(response.headers().getContentType());
return response.writeTo(exchange, new HtmlExceptionHandler.ResponseContext());
}

/**
* 参考AbstractErrorWebExceptionHandler
*/
private class ResponseContext implements ServerResponse.Context {

@Override
public List<HttpMessageWriter<?>> messageWriters() {
return HtmlExceptionHandler.this.messageWriters;
}

@Override
public List viewResolvers() {
return HtmlExceptionHandler.this.viewResolvers;
}

}
}

配置日志输出到外部路径,在yml文件中配置

logging:
pattern:
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"
path: "../"
file: "../sb-business-test.log"
file.max-size: 10MB # 支持KB,MB,GB
level:
root: INFO

-Dreactor.netty.http.server.accessLogEnabled=true
通过logback.xml配置日志输出











%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n








${DEV_FILE_PATH}/my.log.%d{yyyy-MM-dd}.log

30



%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n



10MB





${DEV_FILE_PATH}/access_log.log

%d[%level]%M:%m%n



对sql等进行监控使用阿里巴巴监控配置
# 监控配置
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
引用jar

com.alibaba
druid

打开监控页面
http://127.0.0.1:8080/bwprocess/druid/index.html
动态加载properties里边的属性
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "security.api")
@Data
public class ApiProperties {

private String baseUrl;

private String clientId;

private String clientSecret;
}

posted on 2020-07-21 17:12  泳之  阅读(202)  评论(0编辑  收藏  举报

我是谁? 回答错误