关于spring cloud的核心组件介绍可看这篇博客核心组件
- 创建父级项目springcloud(maven项目或者springboot项目都行)
- 创建eureka服务子模块
- 创建common模块
- 创建测试服务子模块 server-test
- 创建feign子模块调用服务
- 测试
1、创建父级项目springcloud(maven项目或者springboot项目都行)
最终的整体结构如下
2、创建eureka服务子模块
Eureka是微服务架构中的注册中心,专门负责服务的注册与发现。
之后在启动类上添加注解@EnableEurekaServer,表示将项目作为SpringCloud中的注册中心。
EurekaServerApplication.java
package comshun.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
修改application.yml
server:
port: 8001 #服务启动后监听端口
eureka:
instance:
hostname: localhost #服务实例访问ip
client:
register-with-eureka: false #本身为服务注册中心,不需要注册
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #需要注册到该中心的服务需要访问的地址url
spring:
application:
name: eureka-server #该注册中心的名称
到这里eureka-server模块基本配置完毕,启动eureka-server项目,访问http://localhost:8001/
如上图说明启动成功,目前还没有服务注册。
3、创建common模块
新建一个springboot或maven项目结构如下
测试使用的主体就是entity包下的对应数据库表的实体类TbUserInfo ,其他都默认不用改动
TbUserInfo.java
package com.shun.common.entity;
import java.io.Serializable;
/**
* (TbUserInfo)实体类
*
* @author kaishun.zhou
* @since 2020-07-16 15:52:04
*/
public class TbUserInfo implements Serializable {
private static final long serialVersionUID = -23956670558848606L;
private String id;
private String username;
private String password;
private Integer age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
maven install打包用于其他模块引入
4、创建测试服务子模块 server-test
整体结构如下
修改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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.shun</groupId>
<artifactId>server-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>server-test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR6</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--自定义的公共模块-->
<dependency>
<groupId>com.shun</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.11</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</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>
</build>
</project>
启动类添加注解
@EnableDiscoveryClient 使其能够让注册中心能够发现,扫描到该服务。
@EnableCircuitBreaker 使用断路器功能
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@MapperScan("com.shun.servertest.dao")
public class ServerTestApplication {
public static void main(String[] args) {
SpringApplication.run(ServerTestApplication.class, args);
}
}
yml配置
server:
port: 8002
spring:
application:
name: service-test
datasource:
name: spring_cloud
url: jdbc:mysql://127.0.0.1:3306/spring_cloud
username: root
password: 123456
# 使用druid数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: entity
logging:
level:
com.serverhi: DEBUG
eureka:
client:
service-url:
defaultZone: http://localhost:8001/eureka/ #服务注册到该地址的服务注册中心
management: #该设置允许该服务可以被http访问,如查看服务 actuator 等信息
endpoints:
web:
exposure:
include: "*"
cors:
allowed-origins: "*"
allowed-methods: "*"
以查询用户列表为例
TbUserInfoController.java
package com.shun.servertest.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.shun.common.entity.TbUserInfo;
import com.shun.servertest.service.TbUserInfoService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* (TbUserInfo)表控制层
*
* @author kaishun.zhou
* @since 2020-07-16 15:17:21
*/
@RestController
@RequestMapping("/tbUserInfo")
public class TbUserInfoController {
/**
* 服务对象
*/
@Resource
private TbUserInfoService tbUserInfoService;
@PostMapping("findAll")
@HystrixCommand(fallbackMethod="findAllErrorCallback")
public List<TbUserInfo> findAll() {
return this.tbUserInfoService.findAll();
}
public List<TbUserInfo> findAllErrorCallback() {
System.out.println("进入server-test error callback");
return null;
}
}
具体实现此处就不贴出来了
启动项目测试本地服务是否正常
测试数据:
postman测试
5、创建feign子模块调用服务
结构如下
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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.shun</groupId>
<artifactId>feign</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>feign</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR6</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--自定义公共模块-->
<dependency>
<groupId>com.shun</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</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>
</build>
</project>
启动添加注解
@EnableFeignClients—启用feign客户端
package com.shun.feign;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args);
}
}
yml配置
eureka:
client:
service-url:
defaultZone: http://localhost:8001/eureka/
server:
port: 8003
spring:
application:
name: service-feign
feign:
hystrix:
enabled: true
调用server-test服务端接口
调用方法
package com.shun.feign.service;
import com.shun.common.entity.TbUserInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @ClassName: ServerTestService
* @Package: com.shun.feign.service
* @Description:
* @Datetime: 2020/7/16 15:32
* @author: kaishun.zhou
*/
@FeignClient(value="service-test", fallback=ServerTestServiceHystrix.class)
public interface ServerTestService {
@PostMapping("/tbUserInfo/findAll")
List<TbUserInfo> findAll();
}
ServerTestServiceHystrix实现ServerTestService ,为失败后的回调,详情如下
package com.shun.feign.service;
import com.shun.common.entity.TbUserInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @ClassName: ServerTestServiceHystrix
* @Package: com.shun.feign.service
* @Description:
* @Datetime: 2020/7/16 15:33
* @author: kaishun.zhou
*/
@Component
public class ServerTestServiceHystrix implements ServerTestService {
@Override
public List<TbUserInfo> findAll() {
System.out.println("findAll()执行失败,回调 feign errorCallBack");
return null;
}
}
添加控制层调用
package com.shun.feign.controller;
import com.shun.common.entity.TbUserInfo;
import com.shun.feign.service.ServerTestService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @ClassName: FeignController
* @Package: com.shun.feign.controller
* @Description:
* @Datetime: 2020/7/16 15:32
* @author: kaishun.zhou
*/
@RestController
@RequestMapping("/tbUserInfo")
public class FeignController {
@Resource
private ServerTestService serverTestService;
@PostMapping("findAll")
public List<TbUserInfo> findAll(){
return serverTestService.findAll();
}
}
6、测试
启动项目 postman测试结构如下
调用成功,现在我们停止server-test服务后再通过postman访问服务 测试熔断机制
无返回值,控制台可以看出,执行了feign子模块下的错误回调。
启动server-test然后手动添加异常模拟server-test内部错误,测试server-test中的熔断机制
,修改代码TbUserInfoController.java
@RestController
@RequestMapping("/tbUserInfo")
public class TbUserInfoController {
/**
* 服务对象
*/
@Resource
private TbUserInfoService tbUserInfoService;
@PostMapping("findAll")
@HystrixCommand(fallbackMethod="findAllErrorCallback")
public List<TbUserInfo> findAll() {
if(true){
throw new RuntimeException("出错了");
}
return this.tbUserInfoService.findAll();
}
public List<TbUserInfo> findAllErrorCallback() {
System.out.println("进入server-test error callback");
return null;
}
}
从feign调用server-test服务
无返回值,且进入server-test模块的错误回调函数。
如果去除server-test模块中的熔断,且手动触发异常,修改server-test中TbUserInfoController.java代码如下
package com.shun.servertest.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.shun.common.entity.TbUserInfo;
import com.shun.servertest.service.TbUserInfoService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* (TbUserInfo)表控制层
*
* @author kaishun.zhou
* @since 2020-07-16 15:17:21
*/
@RestController
@RequestMapping("/tbUserInfo")
public class TbUserInfoController {
/**
* 服务对象
*/
@Resource
private TbUserInfoService tbUserInfoService;
@PostMapping("findAll")
public List<TbUserInfo> findAll() {
if(true){
throw new RuntimeException("出错了");
}
return this.tbUserInfoService.findAll();
}
}
feign访问server-test模块服务结果如下
postman无返回值
客户端控制台打印日志,走了客户端的错误回调。
而服务端serer-test控制台正常报错
至此结束。
其他组件此处暂不介绍,至于为啥很简单,不会。