使用的组件: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: falsefetchRegistry: 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: localhostclient: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: localhostclient: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@LoadBalancedpublic 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;}@AutowiredPersonClient 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);@Componentstatic class PersonClientFallback implements PersonClient {@Overridepublic 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等方法@Dataclass 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());}
}