使用的组件:Eureka、Ribbon、Feign、Hystrix
首先创建一个maven父工程,并提供pom
在 这个pom中指定了springcloud版本以及springboot的版本
<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>cloud-test</groupId>
<artifactId>cloud-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<!-- 声明项目的父项目 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<!-- 添加依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>ek-service</module>
<module>service-provider</module>
<module>service-invoker</module>
<module>ribbon-test</module>
<module>feign-client</module>
<module>hystrix</module>
</modules>
</project>
创建Eureka工程
pom
<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>cloud-test</groupId>
<artifactId>cloud-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ek-service</artifactId>
<dependencies>
<!-- 引用Eureka Server依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
yml配置文件
server:
port: 8761
eureka:
client:
registerWithEureka: false
fetchRegistry: false
启动类
package org.crazyit.cloud;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class FirstServer {
public static void main(String[] args) {
new SpringApplicationBuilder(FirstServer.class).run(args);
}
}
创建服务提供者工程
pom
<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>cloud-test</groupId>
<artifactId>cloud-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>service-provider</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
yml配置文件
spring:
application:
name: first-service-provider
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
启动类
package org.crazyit.cloud;
import java.util.Scanner;
import javax.servlet.http.HttpServletRequest;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@EnableEurekaClient
@RestController
public class FirstServiceProvider {
public static void main(String[] args) {
// new SpringApplicationBuilder(FirstServiceProvider.class).run(args);
// 读取控制台输入作为端口参数
Scanner scan = new Scanner(System.in);
String port = scan.nextLine();
// 设置启动的服务器端口
new SpringApplicationBuilder(FirstServiceProvider.class).properties(
"server.port=" + port).run(args);
}
@GetMapping(value = "/person/{personId}", produces = MediaType.APPLICATION_JSON_VALUE)
public Person findPerson(@PathVariable("personId") Integer personId,
HttpServletRequest request) {
Person person = new Person(personId, "Crazyit", 30);
person.setMessage(request.getRequestURL().toString());
return person;
}
}
package org.crazyit.cloud;
public class Person {
private Integer id;
private String name;
private Integer age;
private String message;
public Person() {
super();
}
public Person(Integer id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
创建服务消费者工程
pom
<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>cloud-test</groupId>
<artifactId>cloud-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>service-invoker</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</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-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
</project>
yml配置文件
server:
port: 9001
spring:
application:
name: first-service-invoker
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
feign:
hystrix:
enabled: true
启动类
package org.crazyit.cloud;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
@RestController
@EnableFeignClients
@EnableCircuitBreaker
public class FirstInvoker {
public static void main(String[] args) {
SpringApplication.run(FirstInvoker.class, args);
}
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
@GetMapping(value = "/router", produces = MediaType.APPLICATION_JSON_VALUE)
public String router() {
RestTemplate restTpl = getRestTemplate();
// 根据应用名称调用服务
String json = restTpl.getForObject(
"http://first-service-provider/person/1", String.class);
return json;
}
@Autowired
PersonClient personClient;
@GetMapping(value = "/router2", produces = MediaType.APPLICATION_JSON_VALUE)
public Person router2() {
return personClient.findById(1);
}
}
package org.crazyit.cloud;
import org.crazyit.cloud.PersonClient.PersonClientFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
//声明调用的服务名称
@FeignClient(name ="first-service-provider",fallback = PersonClientFallback.class)
public interface PersonClient {
@RequestMapping(method = RequestMethod.GET, value = "/person/{personId}")
Person findById(@PathVariable("personId") Integer personId);
@Component
static class PersonClientFallback implements PersonClient {
@Override
public Person findById(Integer personId) {
// 回退方法
System.out.println("执行 findByid 的回退方法,返回一个预先设定好的 Person");
Person p = new Person(-1, "模拟Person", 0);
return p;
}
}
}
package org.crazyit.cloud;
public class Person {
private Integer id;
private String name;
private Integer age;
public Person() {
super();
}
public Person(Integer id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
RibbonTest
<dependencies>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-loadbalancer</artifactId>
<version>2.2.5</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-core</artifactId>
<version>2.2.5</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
public class ChoseServerTest {
public static void main(String[] args) {
// 创建负载均衡器
BaseLoadBalancer lb = new BaseLoadBalancer();
// 添加服务器
List<Server> servers = new ArrayList<Server>();
servers.add(new Server("localhost", 8080));
servers.add(new Server("localhost", 8081));
lb.addServers(servers);
// 进行6次服务器选择
for(int i = 0; i < 6; i++) {
Server s = lb.chooseServer(null);
System.out.println(s);
}
}
}
FeignTest
<dependencies>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>9.5.1</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
<version>9.5.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
</dependencies>
import lombok.Data;
import feign.Param;
import feign.RequestLine;
/**
* Person客户端服务类
*/
public interface PersonClient {
@RequestLine("GET /person/{personId}")
Person findById(@Param("personId") Integer personId);
// 为所有属性加上setter和getter等方法
@Data
class Person {
Integer id;
String name;
Integer age;
String message;
}
}
import org.crazyit.cloud.PersonClient.Person;
import feign.Feign;
import feign.gson.GsonDecoder;
/**
* Person服务的运行主类
*
*
*/
public class PersonMain {
public static void main(String[] args) {
PersonClient personClient = Feign.builder().decoder(new GsonDecoder())
.target(PersonClient.class, "http://localhost:8081/");
// 调用/person/{personId}服务
Person person = personClient.findById(2);
System.out
.println(person.id + "---" + person.name + "---" + person.age+"---"+person.getMessage());
}
}