最近准备写个小项目,想用springboot+springcloud,注册中心选用euerka,对于服务调用选用了风格比较符合平时开发习惯的feign,选择的原因很简单,之前没用过练习一下(手动滑稽),内容比较全,遇到的各种小坑都找到了对应的解决方案,本次搭建过程中遇见的坑全部红色加粗提示,废话不说,开始搭建。
1. maven: 3.5.3
2. jdk: 1.8
3. 开发工具: Idea
虽然四个project放在一起了,但我是各自维护pom.xml的
一、搭建注册中心euerka(这步没有坑,很简单就搭好了)
1. 修改pom.xml
4.0.0
com.joab.anime
one-for-all-eureka
1.0.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-parent
2.0.3.RELEASE
UTF-8
UTF-8
1.8
Finchley.RELEASE
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
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
4.0.0
com.joaby.springclouddemo
api
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-parent
2.0.3.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
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
4.0.0
com.joaby.springclouddemo
provider
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-parent
2.0.3.RELEASE
UTF-8
UTF-8
1.8
Finchley.RELEASE
com.joaby.springclouddemo
api
1.0-SNAPSHOT
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
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
4.0.0
com.joaby.springclouddemo
customer
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-parent
2.0.3.RELEASE
UTF-8
UTF-8
1.8
Finchley.RELEASE
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-openfeign
com.joaby.springclouddemo
api
1.0-SNAPSHOT
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-maven-plugin
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,显示如下(断路器生效)