SpringCloud中fegin的使用是很是优雅的,被大多数面向接口编程的程序员喜欢,并且熔断(hystrix)则能在服务不可达时快速给客户端一个默认响应。能够说是很不错的机制,今天咱们就来了解一下这两个。java
①,用idea创建一个空工程程序员
②,添加一个pom类型的父模块web
③,给父工程添加子模块便可spring
④,结构以下apache
⑤,eclipse就更简单了,直接创建一个pom类型的父工程,右键父工程给其添加子模块便可编程
①,pom.xmlapi
<?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.example</groupId> <artifactId>spc-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <!--这里必定要是pom,否则公共的api模块会没法install--> <packaging>pom</packaging> <name>spc-parent</name> <description>Demo project for Spring Boot</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <!-- 父类工程管理机制 --> <dependencyManagement> <dependencies> <!--springcloud 依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR1</version> <type>pom</type> <scope>import</scope> </dependency> <!--springboot依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>1.5.12.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <resources> <resource> <directory>src/main/resources</directory><!-- 这个路径下的文件运行访问 --> <filtering>true</filtering> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <delimiters> <delimit>$</delimit><!-- 访问被$包围的值 --> </delimiters> </configuration> </plugin> </plugins> </build> </project>
①,pom.xmlspringboot
<?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> <!--保留名字--> <artifactId>api</artifactId> <!--父工程--> <parent> <groupId>com.example</groupId> <artifactId>spc-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies><!-- 依赖fegin --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> <version>1.3.1.RELEASE</version> </dependency> </dependencies> </project>
②,用到的pojo app
import java.util.Date; public class Ticket { private Integer id; private String name; private Date buyDate; }
③,定义接口eclipse
import com.example.api.bean.Ticket; import com.example.api.factory.TickClientServiceFallbackFactory; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import java.util.List; //必须指定服务名,指定熔断统一处理类 @FeignClient(value = "ticket-provider",fallbackFactory =TickClientServiceFallbackFactory.class) public interface TicketService { // 如下为暴露的服务,与提供者的映射路径一致 @RequestMapping(value = "/ticket/add", method = RequestMethod.POST) public boolean add(Ticket ticket); @RequestMapping(value = "/ticket/get/{id}", method = RequestMethod.GET) public Ticket get(@PathVariable("id") Long id); @RequestMapping(value = "/ticket/list", method = RequestMethod.GET) public List<Ticket> list(); }
④,熔断处理类
import com.example.api.bean.Ticket; import com.example.api.service.TicketService; import feign.hystrix.FallbackFactory; import org.springframework.stereotype.Component; import java.util.Date; import java.util.List; //加入到ioc容器 @Component public class TickClientServiceFallbackFactory implements FallbackFactory<TicketService> { @Override public TicketService create(Throwable cause) { // 经过匿名内部类的方式,若是出错默认结果 return new TicketService() { @Override public boolean add(Ticket ticket) { System.out.println("添加失败^_^"); return false; } @Override public Ticket get(Long id) { Ticket ticket = new Ticket(); ticket.setId(1); ticket.setBuyDate(new Date()); ticket.setName("请稍后重试"); return ticket; } @Override public List<Ticket> list() { return null; } }; } }
①,pom.xml
<artifactId>eureka</artifactId> <parent> <groupId>com.example</groupId> <artifactId>spc-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <!--eureka-server服务端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> </dependencies>
②,application.properties
#eueka 主机名 eureka.instance.hostname=eureka-service #不注册本身 eureka.client.register-with-eureka=false #获取服务 eureka.client.fetch-registry=false #提供者和消费者的注册地址 eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ server.port=8761
③,主配置类
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; //开启eureka @EnableEurekaServer @SpringBootApplication public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } }
①,pom.xml
<artifactId>customer</artifactId> <parent> <groupId>com.example</groupId> <artifactId>spc-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <!-- hystrix --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>com.springcloud</groupId> <artifactId>microservicecloud-api</artifactId> <version>${project.version}</version> </dependency> <!-- Feign相关 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <!-- eureka相关 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> </dependencies>
②,application.properties
server.port=8201 spring.application.name=ticket-customer-fegin eureka.instance.prefer-ip-address=true #注册地址 eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ #开启熔断 feign.hystrix.enabled=true
③,主配置类
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.context.annotation.ComponentScan; //注册到eureka @EnableEurekaClient @SpringBootApplication //指定fegin扫描的包,须要即扫描api工程中熔断配置类 @EnableFeignClients(basePackages= {"com.example.api"}) //须要扫描api工程及本工程注册的bean @ComponentScan("com.example") public class CustomerApplication { public static void main(String[] args) { SpringApplication.run(CustomerApplication.class, args); } }
④,controller层代码编写
import com.example.api.bean.Ticket; import com.example.api.service.TicketService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class CustomerController { @Autowired private TicketService ticketService; @RequestMapping(value = "/fegin/add") public boolean add(Ticket ticket) { return ticketService.add(ticket); } @RequestMapping(value = "/fegin/get/{id}") public Ticket get(@PathVariable("id") Long id) { return ticketService.get(id); } @RequestMapping(value = "/fegin/list") public List<Ticket> list() { return ticketService.list(); } }
①,pom.xml
<artifactId>provider</artifactId> <parent> <groupId>com.example</groupId> <artifactId>spc-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <!-- 引入本身定义的api通用包,能够使用Dept部门Entity --> <dependency> <groupId>com.example</groupId> <artifactId>api</artifactId> <version>${project.version}</version> </dependency> <!-- 将微服务provider侧注册进eureka --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> </dependencies>
②,application.properties
server.port=8002 #服务名 spring.application.name=ticket-provider #使用ip进行注册 eureka.instance.prefer-ip-address=true eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
③,主配置类
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @EnableEurekaClient //启动后注册到eureka @SpringBootApplication public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } }
④,controller层代码
import com.example.api.bean.Ticket; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.util.Collections; import java.util.Date; import java.util.List; @RestController public class TicketController { @RequestMapping(value = "/ticket/add", method = RequestMethod.POST) public boolean add(Ticket ticket) { System.out.println("添加成功"); return true; } @RequestMapping(value = "/ticket/get/{id}", method = RequestMethod.GET) public Ticket get(@PathVariable("id")Long id) { Ticket ticket = new Ticket(); ticket.setId(1); ticket.setBuyDate(new Date()); ticket.setName("《男儿当自强》"); return ticket; } @RequestMapping(value = "/ticket/list", method = RequestMethod.GET) public List<Ticket> list() { System.out.println("找到了好多数据。。。。"); return Collections.emptyList(); } }
①,启动注册工程(eureka)
②,启动消费者工程,此时已经能够看到效果
③,访问消费者接口,看到以下信息,说明熔断起效果了
④,启动提供者工程,等几秒后,便能正常访问提供者