最近准备写个小项目,想用springboot+springcloud,注册中心选用euerka,对于服务调用选用了风格比较符合平时开发习惯的feign,选择的原因很简单,之前没用过练习一下(手动滑稽),内容比较全,遇到的各种小坑都找到了对应的解决方案,本次搭建过程中遇见的坑全部红色加粗提示,废话不说,开始搭建。
1. maven: 3.5.3
2. jdk: 1.8
3. 开发工具: Idea
虽然四个project放在一起了,但我是各自维护pom.xml的
一、搭建注册中心euerka(这步没有坑,很简单就搭好了)
1. 修改pom.xml
-
<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>com.joab.anime
groupId>
-
<artifactId>one-for-all-eureka
artifactId>
-
<version>1.0.0-SNAPSHOT
version>
-
-
<parent>
-
<groupId>org.springframework.boot
groupId>
-
<artifactId>spring-boot-starter-parent
artifactId>
-
<version>2.0.3.RELEASE
version>
-
<relativePath/>
-
parent>
-
-
<properties>
-
<project.build.sourceEncoding>UTF-8
project.build.sourceEncoding>
-
<project.reporting.outputEncoding>UTF-8
project.reporting.outputEncoding>
-
<java.version>1.8
java.version>
-
<spring-cloud.version>Finchley.RELEASE
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-test
artifactId>
-
<scope>test
scope>
-
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>
2. 编辑application.yml
-
server:
-
port:
8761
-
-
eureka:
-
instance:
-
hostname: localhost
-
client:
-
registerWithEureka:
false
-
fetchRegistry:
false
-
serviceUrl:
-
defaultZone: http:
//${eureka.instance.hostname}:${server.port}/eureka/
-
-
spring:
-
application:
-
name: demo-eureka
3. 编辑EurekaApplication.java
-
@EnableEurekaServer
-
@SpringBootApplication
-
public
class EurekaApplication {
-
public static void main(String[] args) {
-
SpringApplication.run(EurekaApplication.class);
-
}
-
}
4. 启动EurekaApplication,浏览器输入http://localhost:8761/,显示如下证明euerka搭建成功
二、提供服务接口api(该步骤目的是接口与实现分离)
1. 修改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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0
modelVersion>
-
-
<groupId>com.joaby.springclouddemo
groupId>
-
<artifactId>api
artifactId>
-
<version>1.0-SNAPSHOT
version>
-
-
<parent>
-
<groupId>org.springframework.boot
groupId>
-
<artifactId>spring-boot-starter-parent
artifactId>
-
<version>2.0.3.RELEASE
version>
-
<relativePath/>
-
parent>
-
-
<properties>
-
<project.build.sourceEncoding>UTF-8
project.build.sourceEncoding>
-
<project.reporting.outputEncoding>UTF-8
project.reporting.outputEncoding>
-
<java.version>1.8
java.version>
-
properties>
-
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.boot
groupId>
-
<artifactId>spring-boot-starter-web
artifactId>
-
dependency>
-
dependencies>
-
-
project>
2. 提供api接口
-
public
interface IDemoApi {
-
/**
-
* 入参为字段,返回值为字段
-
*/
-
@RequestMapping(value=
"/demo-api/test", method=RequestMethod.GET)
-
String test(@RequestParam(value = "test") String test);
-
/**
-
* 入参为对象,返回值为对象
-
*/
-
@RequestMapping(value=
"/demo-api/user", method=RequestMethod.POST)
-
User user(@RequestBody User user);
-
}
注意:
1)不支持@GetMapping @PostMapping,只能用@RequestMapping,通过method指定请求方式;
2)参数传递必须用@RequestParam(value = "test") 注解修饰;
3)传递的参数为对象,必须用@RequestBody修饰;
4)返回值若为对象,对象必须序列化,且必须提供public修饰的无参构造方法(默认是提供的),会报错com.fasterxml.jackson.databind.exc.InvalidDefinitionException,原因是jackson的反序列化需要无参构造函数;
*5)尽管路径均为“/demo-api/xxx”,但是笔者在类上使用注解@RequestMapping(value="/demo-api")就无法调通,请读者补充
二、提供服务提供者实现
1. 修改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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0
modelVersion>
-
-
<groupId>com.joaby.springclouddemo
groupId>
-
<artifactId>provider
artifactId>
-
<version>1.0-SNAPSHOT
version>
-
-
<parent>
-
<groupId>org.springframework.boot
groupId>
-
<artifactId>spring-boot-starter-parent
artifactId>
-
<version>2.0.3.RELEASE
version>
-
<relativePath/>
-
parent>
-
-
<properties>
-
<project.build.sourceEncoding>UTF-8
project.build.sourceEncoding>
-
<project.reporting.outputEncoding>UTF-8
project.reporting.outputEncoding>
-
<java.version>1.8
java.version>
-
<spring-cloud.version>Finchley.RELEASE
spring-cloud.version>
-
properties>
-
-
<dependencies>
-
<dependency>
-
-
<groupId>com.joaby.springclouddemo
groupId>
-
<artifactId>api
artifactId>
-
<version>1.0-SNAPSHOT
version>
-
dependency>
-
<dependency>
-
<groupId>org.springframework.cloud
groupId>
-
<artifactId>spring-cloud-starter-netflix-eureka-client
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>
-
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>
2. 编辑application.yml
-
server:
-
port:
8091
-
-
eureka:
-
#eueka 主机名
-
instance:
-
hostname: localhost
-
client:
-
#提供者和消费者的注册地址
-
service-url:
-
defaultZone: http:
//${eureka.instance.hostname}:8761/eureka/
-
-
spring:
-
application:
-
name: demo-provider
3. 实现服务
-
@RestController
-
public
class DemoProvider implements IDemoApi {
-
@Override
-
public String test(String test) {
-
return
"test: " + test;
-
}
-
-
@Override
-
public User user(@RequestBody User user) {
-
if (user ==
null) {
-
user =
new User(
10,
"Joab-Y");
-
}
-
return user;
-
}
-
}
3. 编辑ProviderApplication.java
-
@SpringBootApplication
-
@EnableEurekaClient
-
public
class ProviderApplication {
-
public static void main(String[] args) {
-
SpringApplication.run(ProviderApplication.class);
-
}
-
}
4. 启动ProviderApplication,浏览器输入http://localhost:8091/demo-api/test?test=123,显示如下,服务提供成功
注意:
1)实现类必须用@RestController注解修饰,不然他会去找模板;
2)传递参数如果为对象,该对象必须再次用@RequestBody修饰,不然字段带不过来,仍为null;
四、搭建消费者
1. 修改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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0
modelVersion>
-
-
<groupId>com.joaby.springclouddemo
groupId>
-
<artifactId>customer
artifactId>
-
<version>1.0-SNAPSHOT
version>
-
-
<parent>
-
<groupId>org.springframework.boot
groupId>
-
<artifactId>spring-boot-starter-parent
artifactId>
-
<version>2.0.3.RELEASE
version>
-
<relativePath/>
-
parent>
-
-
<properties>
-
<project.build.sourceEncoding>UTF-8
project.build.sourceEncoding>
-
<project.reporting.outputEncoding>UTF-8
project.reporting.outputEncoding>
-
<java.version>1.8
java.version>
-
<spring-cloud.version>Finchley.RELEASE
spring-cloud.version>
-
properties>
-
-
<dependencies>
-
<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>
-
dependency>
-
<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>com.joaby.springclouddemo
groupId>
-
<artifactId>api
artifactId>
-
<version>1.0-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>
2. 编辑application.yml
-
server:
-
port:
8081
-
-
spring:
-
application:
-
name: demo-customer
-
-
eureka:
-
#eueka 主机名
-
instance:
-
hostname: localhost
-
client:
-
#提供者和消费者的注册地址
-
serviceUrl:
-
defaultZone: http:
//${eureka.instance.hostname}:8761/eureka/
-
feign:
-
hystrix:
-
enabled:
true
3. 编辑DemoFeignService接口,继承服务api
-
// name: 服务者application.yml中的spring.application.name
-
// fallback: 断路器执行方法,即方法执行失败调用
-
@FeignClient(name=
"demo-provider", fallback = DemoServiceFallback.class)
-
public
interface DemoFeignService extends IDemoApi {
-
}
4. 实现断路器类
-
@Component
-
public
class DemoServiceFallback implements DemoFeignService {
-
@Override
-
public String test(String test) {
-
return
"error";
-
}
-
-
@Override
-
public User user(User user) {
-
return
null;
-
}
-
}
5. 前端调用
-
@RestController
-
public
class DemoController {
-
@Autowired
-
public DemoFeignService demoFeignService;
-
-
@RequestMapping(
"/test")
-
public String test() {
-
return demoFeignService.test(
"test");
-
}
-
-
@RequestMapping(
"/user")
-
public User user() {
-
User user =
new User();
-
user.setAge(
10);
-
user.setName(
"Joab-Y");
-
return demoFeignService.user(user);
-
}
-
}
6. 编辑CustomerApplicaton.java
-
@SpringBootApplication
-
@EnableEurekaClient
-
@EnableDiscoveryClient
-
@EnableFeignClients
-
public
class CustomerApplicaton {
-
public static void main(String[] args) {
-
SpringApplication.run(CustomerApplicaton.class, args);
-
}
-
}
7. 启动CustomerApplicaton
浏览器输入http://localhost:8081/test,显示如下
浏览器输入http://localhost:8081/user,显示如下
若断开provider,浏览器输入http://localhost:8081/test,显示如下(断路器生效)