创建一个服务,首先得明白这个服务既是服务的提供者service又是服务的消费者client。
一、创建服务:service-user
1、项目创建:同注册中心创建过程,只是在包依赖时不同。
创建完成之后:
2、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.hx.demo</groupId> <artifactId>service-user</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>service-user</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </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>Edgware.SR3</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-devtools</artifactId> <scope>runtime</scope> </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-eureka</artifactId> </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>
3、启动类注解配置:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class ServiceUserApplication { public static void main(String[] args) { SpringApplication.run(ServiceUserApplication.class, args); } }
4、application.yml配置:
eureka: client: serviceUrl: defaultZone: http://localhost:9000/eureka/ server: port: 9001 spring: application: name: service-user
defaultZone:声明注册中心地址
name:服务名称
5、启动应用:
如图,应用已成功注入:
服务名为:SERVICE-USER
6、添加服务调用接口:
@RestController @RequestMapping("/user/") public class UserController { @Value("${server.port}") private String port; @RequestMapping("sayHello") public String getUser(@RequestBody String say){ return say + " say hello! port=" + port; } }
7、使用Postman调用:
结果如图,调用结果。
二、创建服务:service-user-1 再次创建服务,创建内容和以上一样。仅修改端口号。
eureka: client: serviceUrl: defaultZone: http://localhost:9000/eureka/ server: port: 9002 spring: application: name: service-user
三、基于rest+ribbon创建服务:作为服务的调用者,创建步骤同上。
1、添加启动配置:RestTemplate 表明开启负载均衡
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableEurekaClient public class ServiceUserApplication { public static void main(String[] args) { SpringApplication.run(ServiceUserApplication.class, args); } /** * 向程序的ioc注入一个bean: restTemplate;并通过@LoadBalanced注解表明这个restRemplate开启负载均衡的功能。 * @return */ @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }
2、创建一个接口,调用服务SERVICE-USER
@RestController @RequestMapping("/user/") public class UserController { @Autowired private RestTemplate restTemplate; @RequestMapping("sayHello") public String getUser(@RequestBody String say){ ResponseEntity<String> result = restTemplate.postForEntity("http://SERVICE-USER/user/sayHello", say, String.class); System.out.println(result); return result.getBody(); } }
3、启动后:
可以发现,SERVICE-USER服务有两个端口,分别是9001和9002
4、通过端口9003调用
5、调用结果:很显然实现了实现了负载均衡。访问了9001和9002两端口,
四、基于Feign创建服务:作为客户端,调用服务提供者
1、pom.xml依赖:主要添加spring-cloud-starter-eureka 和spring-cloud-starter-feign两个依赖包
<?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.hx.demo</groupId> <artifactId>client-1</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>service-user</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </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>Edgware.SR3</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-devtools</artifactId> <scope>runtime</scope> </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-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </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配置:
eureka: client: serviceUrl: defaultZone: http://localhost:9000/eureka/ server: port: 9004 spring: application: name: client-1
3、启动类配置
3.1、注解@EnableDiscoveryClient
spring cloud中discovery service有许多种实现(eureka、consul、zookeeper等等),@EnableDiscoveryClient基于spring-cloud-commons, @EnableEurekaClient基于spring-cloud-netflix。
可以这样理解:如果选用的注册中心是eureka,那么就推荐@EnableEurekaClient,如果是其他的注册中心,那么推荐使用@EnableDiscoveryClient。
3.2、@EnableFeignClients:声明开启Feign的功能
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class ServiceUserApplication { public static void main(String[] args) { SpringApplication.run(ServiceUserApplication.class, args); } }
4、写一个服务调用接口@FeignClient 声明这是一个服务调用接口
@FeignClient括号内为调用服务名
细心点会发现这里调用名用的是小写,与RestTemplate 调用接口用大小有差异。其实这里大小写都可以。
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @FeignClient("service-user") public interface UserService { @RequestMapping(value = "/user/sayHello",method = RequestMethod.POST) String say(String say); }
5、controller写一个对外接口,供外部调用
@RestController @RequestMapping("/user/") public class UserController { @Autowired private UserService userService; @RequestMapping("sayHello") public String getUser(@RequestBody String say){ String result = userService.say(say); System.out.println(result); return result; } }
6、启动项目,请求调用
7、调用结果分析:
可见Feign默认实现了负载均衡,查看源码不难发现:Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。
最后:github地址:https://github.com/houxi1234/demo.git