前言
大家好啊,明天就是国庆节了,今天再发一篇博客。
其实本篇博客,是连接上一篇博客来的。
手把手搭建springCloud框架(二)——eureka客户端+swagger+mybatisPlus: juejin.cn/post/684490…
因此,本篇博文,是从上一篇博文创建的项目发展而来,请先搭建上一篇博文所有的项目后,再来搭建本项目。
内容
上一篇博文的项目目录:
本篇博文搭建成功后的项目目录:
因此,需要注意的是以下内容,我将一一贴出来,给到大家。
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.blog</groupId>
<artifactId>permission-service</artifactId>
<version>0.0.1-permissionService-SNAPSHOT</version>
<packaging>jar</packaging>
<name>permission-service</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--引入mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
<!--引入mybatisPlus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.1.8</version>
</dependency>
<!-- 模板引擎 代码生成 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<!-- mysql驱动器依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--springboot的web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Herbnate实体依赖-->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>
<!--常用基础Jar包,构建自己的thrift连接池-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- 引入Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!--spring默认使用yml中的配置,但有时候要用传统的xml或properties配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- 解析json数据的依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.41</version>
</dependency>
<!-- jwt认证协议依赖,token授权依赖 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<!--这是权限认证依赖,这个需要屏蔽,不然使用eureka到swagger会需要登录-->
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>-->
<!-- 这三个依赖,是为了序列化对象转换为json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<!--********************************************************************************-->
<!--springCloud启动依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<!--srpingCloud的eureka服务注册依赖,client端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<!--srpingCloud的eureka服务注册依赖,server端,是因为本服务既要充当生产者,又要充当消费者-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<!--springCloud的fiegn依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!--springCloud的ribbon依赖-->
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon</artifactId>
<version>2.2.2</version>
</dependency>
<!--histrix依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<!--Hystrix 的一个类库-->
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
</dependency>
<!--新增依赖,swaggerUI-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
</dependencies>
<!-- 引入spring cloud的依赖,不能少,主要用来管理Spring Cloud生态各组件的版本 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<!--需要打包的目录-->
<directory>src/main/resources</directory>
<!--目录中的文件类型-->
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<finalName>permission</finalName>
</build>
</project>
application.properties
#服务名
spring.application.name=permission
#端口
server.port=3333
################################################################################################################
#数据库信息
spring.datasource.url: jdbc:mysql://localhost:3306/myblog?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username: root
spring.datasource.password: 123456
spring.datasource.driver-class-name: com.mysql.jdbc.Driver
#################################################################################################################
spring.jmx.default-domain=${spring.application.name}
spring.jpa.open-in-view=false
# springframework.web日志以DEBUG级别输出
logging.level.org.springframework.web=info
###############################################################################################################
# 如果是放在src/main/java目录下 classpath:/com/blog/*/mapper/*Mapper.xml
# 如果是放在resource目录 classpath:/mapper/*Mapper.xml
mybatis-plus.mapper-locations=classpath:/mapper/*Mapper.xml
#实体扫描,多个package用逗号或者分号分隔
mybatis-plus.type-aliases-package=com.blog.*.entity
#驼峰下划线转换
mybatis-plus.global-config.db-column-underline=true
#刷新mapper 调试神器
mybatis-plus.global-config.refresh-mapper=false
#数据库大写下划线转换
mybatis-plus.global-config.capital-mode=true
#################################################################################################################
#配置Swagger相关信息(从eureka跳到swagger页面)
eureka.instance.prefer-ip-address=true
eureka.instance.hostname=:${spring.cloud.client.ipAddress}
eureka.instance.status-page-url:http://${spring.cloud.client.ipAddress}:${server.port}/swagger-ui.html
####################################################################################################################
#eureka注册中心路径
eureka.client.service-url.defaultZone=http://localhost:1111/eureka/
#表示本服务发送给eureka服务端的心跳时间,设置时间不能太长,不然会导致eureka检测不到服务从而会驱逐服务下线
eureka.instance.leaseRenewalIntervalInSeconds: 2
#当本服务掉线后,eureka服务端取掉本服务的缓存的时间
eureka.instance.leaseExpirationDurationInSeconds: 4
#注册到eureka上的服务的名字
eureka.instance.instance-id=http://${spring.cloud.client.ipAddress}:${server.port}/${spring.application.name}
#######################################################################################################################
#逻辑删除配置(下面3个配置),不是真实删除数据,只是逻辑删除数据
mybatis-plus.global-config.logic-delete-value=1
mybatis-plus.global-config.logic-not-delete-value=0
mybatis-plus.global-config.sql-injector=com.baomidou.mybatisplus.mapper.LogicSqlInjector
##############################################################################################################
mybatis-plus.global-config.meta-object-handler=com.blog.permission.mabatisPlus.MyMetaObjectHandler
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.cache-enabled=false
mybatis-plus.configuration.jdbc-type-for-null=null
mybatis-plus.typeAliasesPackage=com.blog.permission.entity
mybatis-plus.global-config.id-type=3
mybatis-plus.global-config.field-strategy=2
mybatis-plus.global-config.key-generator=com.baomidou.mybatisplus.incrementer.OracleKeyGenerator
##############################################################################################################
#默认的超时时间设置
hystrix.metrics.polling-interval-ms=60000
#启动Hystrix
hystrix.metrics.enabled=true
##############################################################################################################
#将日志放到项目里面的logs文件夹的permission.log文件中
logging.file=logs/permission.log
##############################################################################################################
PermissionApplication.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableFeignClients //feign注解
@ComponentScan(basePackages = "com.blog.permission")
@EnableAsync //支持多线程
@EnableSwagger2 //swagger注解
@EnableWebMvc //配合WebMvcConfig配置文件,目的是为了使用webMVC
@SpringBootApplication
@EnableEurekaClient //注册到eureka上的注解
@EnableCircuitBreaker //Hystrix熔断机制的注解
public class PermissionApplication {
public static void main(String[] args) {
SpringApplication.run(PermissionApplication.class, args);;
}
}
接下来,是要添加一个测试Feign和Hystrix的接口:
controller层
代码:@ApiOperation(value = "测试feign的接口")
@PostMapping("/testForFeign")
public Result testForFeign(@ApiParam(value = "用户id")@RequestParam(required = false) String userId){
return userService.testForFeign(userId);
}
service层
@Override
public Result testForFeign(String userId) {
Result result=perimissionFallback.get(userId);
return result;
}
新增:perimissionFallback.java
import com.blog.permission.feign.PermissionClient;
import com.blog.permission.method.Result;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class PerimissionFallback {
@Resource
private PermissionClient permissionClient;
private static final Logger logger = LoggerFactory.getLogger(PerimissionFallback.class);
@HystrixCommand(fallbackMethod = "getFallBack")
public Result get(String userId) {
Result result=permissionClient.get(userId);
return result;
}
public Result getFallBack(String userId) {
logger.info("调用接口:permission/login/get 失败,降级处理");
return new Result().fallBack("permission/login/get",userId);
}
}
代码里面的注解:@HystrixCommand(fallbackMethod = "getFallBack"),这个就是引入了Hystrix的方法降级,降级的方法就是getFallBack这个方法,图片中我用红色箭头标出来了,很容易理解。
新增:PermissionClient.java
import com.blog.permission.method.Result;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
@Component
@FeignClient(value = "permission")
public interface PermissionClient {
//这是跨服务调用permission服务的“permission/login/get”接口
@RequestMapping(value = "/login/get", method = RequestMethod.GET)
public Result get(@RequestParam("userId") String userId);
}
可以看一下,这个跨服务想要调用的方法是这样的:
对比一下上面的代码,会发现有什么不同的地方呢?好的,现在可以开始启动服务了。
表示服务已经启动成功,打开网页,输入网址:localhost:1111,如果不知道这个网址是怎么了,请查看我之前的一篇系列博文:手把手搭建springCloud框架(一)——eureka的服务端(server)的搭建:juejin.cn/post/684490…
点击:http://192.168.2.92:3333/permission ,进入到swagger页面。
调用接口,开始测试:
可以看到,我测试Feign跨服务是成功了的,当然,我这次测试是自己跨服务调用自己,当然会有问题,不过这里暂且不提。接下来,我们开始测试Hystrix的熔断机制。 在接口:login/get里的service层打断点
然后再在swagger上调用接口,我们发现,当打上断点到一点的时间点(其实就是我们设置的Hystrix的熔断时间,仔细看一下我们的配置文件,application.properties),然后再去掉断点,让程序运行,那么调用接口就会失败,返回的内容也是我们自己定义的返回内容: 这个返回内容,不就是我们自己定义的fallBack方法吗?讲到这里,我们已经将Feign和Hystrix讲了,那么Ribbon在哪里呢?当你开始使用Feign的时候,只要你的依赖里面有Ribbon,那么springCloud会默认使用Ribbon来进行分发Feign的请求,所以我们无须关心这一点。
总结
这个搭建过程,其实还是比较曲折的,原因就是网上的一些技术博客,可能由于springboot和springCloud的依赖版本不同,其实不能给到我帮助,因此许多的配置方面的东西,我都需要自己去看官方文档,这个就比较累了。
最后,希望能够帮助看到这篇文章的你。