版权声明:本文为博主原创文章,欢迎转载。 https://cloud.tencent.com/developer/article/1454228
2019年6月,当前最新版Greenwich.SR1发布。
参考官方文档
https://cloud.spring.io/spring-cloud-static/Greenwich.SR1/single/spring-cloud.html
我们新建一个普通的Maven项目,项目名称cloud,对应的pom.xml文件说明如下。
该pom文件作为父级pom文件,起到依赖版本控制的作用,其他Module模块均继承该pom。
<?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.cntaiping.tpa</groupId>
<artifactId>cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>cloud</name>
<description>Demo project for Spring Boot</description>
<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>Greenwich.SR1</spring-cloud.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/>
</parent>
<modules>
<module>register-server</module>
<module>producer</module>
<module>consumer</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>
我们需要在cloud项目中新建3个Module模块,服务注册中心(register-server)、服务生产者(producer)和服务消费者(consumer)
新建Module模块的基本方法:
选择Maven项目cloud,右键单击–>New–>Module–>选择spring initialir
也就是新建一个SpringBoot模块。
新建服务注册中心模块(register-server),也是一个SpingBoot模块。
修改对应的pom文件,内容如下,继承父级pom文件。
<?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.cntaiping.tpa.cloud</groupId>
<artifactId>register-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>register-server</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.cntaiping.tpa</groupId>
<artifactId>cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
#注册中心服务ID
spring.application.name=register-server
#端口号
server.port=8800
# eureka.client.registerWithEureka :表示是否将自己注册到Eureka Server,默认为true。
# 由于当前这个应用就是Eureka Server,故而设为false
eureka.client.register-with-eureka=false
# eureka.client.fetchRegistry :表示是否从Eureka Server获取注册信息,默认为true。因为这是一个单点的Eureka Server,
# 不需要同步其他的Eureka Server节点的数据,故而设为false。
eureka.client.fetch-registry=false
# eureka.client.serviceUrl.defaultZone :设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址。默认是
eureka.client.serviceUrl.defaultZone=http://localhost:8800/eureka/
需要指明spring.application.name
参数,这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name。
需要添加一个注解@EnableEurekaServer
package com.cntaiping.tpa.cloud.registerserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class RegisterServerApplication {
public static void main(String[] args) {
SpringApplication.run(RegisterServerApplication.class, args);
}
}
No application available
表示没有服务被发现, 因为现在还没有服务提供者进行注册服务。
新建服务生产者模块(producer)。服务的提供方可以看做是服务注册中心的客户端,所以需要引入spring-cloud-starter-netflix-eureka-client。
修改对应的pom文件,内容如下。
<?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.cntaiping.tpa</groupId>
<artifactId>producer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>producer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.cntaiping.tpa</groupId>
<artifactId>cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
#服务名称
spring.application.name=producer
#端口号
server.port=8700
#在注册中心中进行注册
eureka.client.serviceUrl.defaultZone=http://localhost:8800/eureka/
#启动服务发现的功能,开启了才能调用其它服务
spring.cloud.config.discovery.enabled=true
#发现的服务的名字--对应注测中心的服务名字
spring.cloud.config.discovery.serviceId=register-server
需要添加一个@EnableEurekaClient注解 表明自己是一个eurekaclient
package com.cntaiping.tpa.producer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class ProducerApplication {
public static void main(String[] args) {
SpringApplication.run(ProducerApplication.class, args);
}
}
服务生产者提供的具体服务如下,这里只是一个简单例子,返回一个字符串。
package com.cntaiping.tpa.producer.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MessageController {
@Value("${server.port}")
String port;
@GetMapping("/get")
public String getMessage(@RequestParam("name")String name){
return "Hi " + name + " ,I am from port:" + port;
}
}
当服务提供方任务繁重时,可以多起几个该服务的实例,通过负载均衡来解决。
这里我们通过多端口来启动服务生产者producer模块的多个实例。
第一步:在IntelliJ IDEA右上角点击XXXXApplication右边的下三角,弹出下拉框,点击“Edit Configuration…”
第二步:复制服务生产者模块(producer)的实例
通过复制按钮复制服务生产者模块(producer)的实例,这样就有两个实例了。为了区别,修改了实例名称Name,分别加上了启动端口号做后缀。
实例配置:将默认的Single instance only(单实例)的钩去掉,VM options中添加“-Dserver.port=8700”,表示将从8700端口启动一个实例。另一个实例端口修改为8701即可。
分别运行服务生产者模块(producer)的两个实例,效果如下。
再次刷新注册中心页面,可以发现服务生产者的两个实例(8700和8701)
同样新建一个服务消费者模块,名称是consumer。
修改pom文件内容如下。
<?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.cntaiping.tpa</groupId>
<artifactId>consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>consumer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.cntaiping.tpa</groupId>
<artifactId>cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
</project>
Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign。这里我们采用ribbon+restTemplate方式,pom文件中增加了spring-cloud-starter-netflix-ribbon依赖。
这里配置文件采用yml格式,服务消费者模块的端口号是 8600。
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8800/eureka/
server:
port: 8600
spring:
application:
name: consumer
相同点:@EnableDiscoveryClient和@EnableEurekaClient都是能够让注册中心能够发现,扫描到改服务。
不同点:@EnableEurekaClient只适用于Eureka作为注册中心,@EnableDiscoveryClient 可以是其他注册中心。
从Spring Cloud Edgware开始,@EnableDiscoveryClient 或@EnableEurekaClient 可省略。只需加上相关依赖,并进行相应配置,即可将微服务注册到服务发现组件上。
package com.cntaiping.tpa.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
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
@EnableDiscoveryClient
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@LoadBalanced //使用负载均衡机制
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
服务消费类如下,通过Spring DI注入的restTemplate来消费producer的“/get”接口
package com.cntaiping.tpa.consumer.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class MessageController {
@Autowired
RestTemplate restTemplate;
@GetMapping("/show")
public String showMessage(@RequestParam String name){
return restTemplate.getForObject("http://producer/get?name="+name, String.class);
}
}
http://localhost:8600/show?name=chengyq