springcloud是java的微服务方案,这里我就直接全用起来。
这里依然选择java8, spring-boot 似乎是2.几的版本。
首先,oauth使用jwt在spring-boot;
然后, eureka server, 用来服务发现等; zookeeper;
再然后, 服务注册使用eureka;
再然后,使用zuul proxy server 配置路由和网关;
再然后,配置configuration server和configuration client;
再然后, acturator, 对终结点进行管理,主要进行请求监控,性能等管理;
再然后, admin server, admin client 集中对所有终结点进行管理监控;
再然后, hystrix, 进行fallback和错误时的处理;
再然后, kafaka, 作为消息队列在微服务间进行消息通讯;
再然后, 集中日志管理, sleuth;
首先创建一个maven 的springboot项目,service 模板项目作为所有项目的启动,集成所有基础模块和功能;因为想用java1.8, 这里需要支持java1.8的版本的springcloud 版本,最新的似乎是springcloud 2.2.x;
找到上次的springboot项目,拷贝一份,修改名称,添加pom.xml中的依赖, 打包方式为jar/war,war为tomcat等 servlet容器布署方式,此时springboot 入口代码有区别; 端口配置默认为 application.properties文件,或者为application.yml文件,或者java -jar
-Dspring.config.location = C:\application.properties
project1.jar 这样指定配置文件位置;
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion> 4.0.0 </modelVersion> <groupId> org.example </groupId> <artifactId> springboot1 </artifactId> <packaging> <!-- war --> jar </packaging> <version> 1.0-SNAPSHOT </version> <parent> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-starter-parent </artifactId> <version> 2.3.1.RELEASE </version> <relativePath /> </parent> <dependencies> <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-starter-web </artifactId> </dependency> <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot </artifactId> <version> 2.3.1.RELEASE </version> </dependency> <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-starter-actuator </artifactId> </dependency> <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-starter-security </artifactId> </dependency> <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-starter-thymeleaf </artifactId> </dependency> <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-starter-test </artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-maven-plugin </artifactId> <configuration> <fork> false </fork> </configuration> </plugin> </plugins> </build> <properties> <maven.compiler.source> 8 </maven.compiler.source> <maven.compiler.target> 8 </maven.compiler.target> <project.build.sourceEncoding> UTF-8 </project.build.sourceEncoding> <start-class> springboot1.App </start-class> </properties> </project> |
多个properties文件作为dev 或者prod, application-dev/prod.xml, 运行时指定 java -jar app1.jar --spring.profiles.active=dev;
配置logging:
debug = true
logging.path = ./logs/
private static final Logger logger = LoggerFactory.getLogger(FrontController.class);
logger.info("this is a info message");
logger.warn("this is a warn message");
logger.error("this is a error message");
由于添加了springboot-starter-security, 会默认保护, 用户名和密码为user, 密码在控制台打印出;
将logback.xml直接放在resource下面,日志会自动打印生成文件;
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern> [%d{yyyy-MM-dd'T'HH:mm:ss.sss'Z'}] [%C] [%t] [%L] [%-5p] %m%n </pattern> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <File> mylog1.log </File> <encoder> <pattern> [%d{yyyy-MM-dd'T'HH:mm:ss.sss'Z'}] [%C] [%t] [%L] [%-5p] %m%n </pattern> </encoder> </appender> <root level="INFO"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </root> </configuration> |
全局异常捕获,在代码中throw new ProductNotfoundException(), 此处就会跑到exception controller:
@ControllerAdvice public class ProductExceptionController { @ExceptionHandler(value = ProductNotfoundException.class) public ResponseEntity<Object> exception(ProductNotfoundException exception) { return new ResponseEntity<>("Product not found", HttpStatus.OK); }
} |
Interceptor,注册到所有路径和排除路径:
import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @Component public class ProductServiceInterceptor implements HandlerInterceptor { @Override public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Pre Handle method is Calling"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("Post Handle method is Calling"); } @Override public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception {
System.out.println("Request and Response is completed"); } } |
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Component public class ProductServiceInterceptorAppConfig extends WebMvcConfigurerAdapter { @Autowired ProductServiceInterceptor productServiceInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(productServiceInterceptor).addPathPatterns("/**").excludePathPatterns("/login"); } } |
添加filter, 直接会过滤请求:
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.springframework.stereotype.Component; @Component public class SimpleFilter implements Filter { @Override public void destroy() {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain) throws IOException, ServletException {
System.out.println("Remote Host:"+request.getRemoteHost()); System.out.println("Remote Address:"+request.getRemoteAddr()); filterchain.doFilter(request, response); } @Override public void init(FilterConfig filterconfig) throws ServletException {} } |
搭建的包括security, logging, global exception, dev profiles, interceptor, filter, 所有结果:
refs:
https://www.jb51.net/program/297972d0o.htm
https://www.tutorialspoint.com/spring_boot/spring_boot_zuul_proxy_server_and_routing.htm
https://blog.51cto.com/u_16175439/6815240
https://spring.io/projects/spring-cloud
https://blog.csdn.net/private_name/article/details/121648469
https://www.tutorialspoint.com/spring_boot/spring_boot_building_restful_web_services.htm