0、说明
版本:版本选择
SpringBoot版本:2.3.2.RELEASE
spring-cloud版本:Hoxton.SR9
spring-cloud-alibaba版本:2.2.6.RELEASE
服务注册与发现:
Nacos
远程调用:
openfeign,SpringCloud的子项目之一,是一种声明式、模块化的Http客户端,通过集成Ribbon实现负载均衡,代替RestTemplete组件,实现远程调用。
1、搭建父工程:shiory-cloud
1、建项目
新建一个maven工程,新建完父工程后,删除src目录,父工程结构
2、改pom.xml文件
在pom.xml文件中锁定SpringBoot、SpringCloud、SpringCloud Alibaba的版本,加入以下内容。dependencyManagement标签是锁定版本,并不是真正的依赖。
<!-- SpringBoot版本--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.2.RELEASE</version> <relativePath/> </parent> <properties> <!--JDK版本--> <java.version>1.8</java.version> <!--字符集编码--> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!--spring-cloud版本--> <spring.cloud-version>Hoxton.SR9</spring.cloud-version> <!--spring-cloud-alibaba版本--> <spring.cloud.alibaba-version>2.2.6.RELEASE</spring.cloud.alibaba-version> </properties> <dependencyManagement> <dependencies> <!--spring-cloud--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring.cloud-version}</version> <type>pom</type> <scope>import</scope> </dependency> <!--spring-cloud-alibaba--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring.cloud.alibaba-version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <repositories> <repository> <id>aliyun</id> <name>aliyun Repository</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
2、提取公共模块:cloud-common
因为微服务项目中,会有很多服务,所以抽取公共部分建成一个模块Module
1、建Module
右键项目--New--Module,选择Maven项目,点击Next,选择父工程,输入模块名称,点击Finish
2、改pom.xml文件
添加如下依赖
<dependencies> <!--web场景依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--端点监控场景依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--Nacos场景依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--openfeign场景依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies>
3、新建application.yml文件
在resources目录下新建application.yml文件,添加公共配置(nacos连接信息,用于服务注册与发现)
spring: cloud: nacos: discovery: server-addr: localhost:8848 # nacos-server的地址 username: nacos # nacos-server用户名 password: nacos # nacos-server密码
4、新建主启动类
在src/main/java中新建一个启动类,添加@EnableDiscoveryClient注解,开启服务注册与发现
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * ===================================================== * 服务公共模块 * @author 汐小旅Shiory * @date 2021/12/5 13:46 * ===================================================== */ @SpringBootApplication @EnableDiscoveryClient // 服务注册与发现 public class CommonApplication { public static void main(String[] args) { SpringApplication.run(CommonApplication.class, args); } }
5、项目结构
3、 搭建服务提供者:cloud-demo1
1、建Module
右键项目--New--Module,选择Maven项目,点击Next,选择父工程,输入模块名称,点击Finish
2、改pom.xml文件
添加刚才新建的公共模块依赖
<dependencies> <!--公共模块依赖--> <dependency> <groupId>com.shiory</groupId> <artifactId>cloud-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
3、新建application.yml文件
在resources目录下新建application.yml文件,并且添加服务名和端口,每个模块的服务名和端口必须保证唯一
server: port: 7001 # 服务端口号,必须配置,保证唯一 spring: application: name: cloud-demo1 # 服务名称,必须配置,保证唯一
4、新建主启动类
在src/main/java中新建一个启动类,和cloud-common一样,把启动类建在同一级目录一下,比如cloud-common的在com.shiory包下,那这个启动类就建在cloud-demo1的com.shiory包下
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * ===================================================== * 服务提供者 * @author 汐小旅Shiory * @date 2021/12/5 13:55 * ===================================================== */ @SpringBootApplication public class Demo1Application { public static void main(String[] args) { SpringApplication.run(Demo1Application.class, args); } }
5、编写对外暴露的接口
也就是要被远程调用的接口:“/demo1/api/callTest”
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * ===================================================== * 服务提供者:对外暴露的接口 * @author 汐小旅Shiory * @date 2021/12/5 14:31 * ===================================================== */ @RestController @RequestMapping("/demo1/api") public class Demo1ApiController { @GetMapping("/callTest") public String callTest(@RequestParam(name = "serverName") String serverName) { String result = "我是服务提供者,我被服务" + serverName + "调用了!"; return result; } }
6、项目结构
4、 抽取公共声明式接口模块:cloud-api
因为暴露的接口不可能只会被一个服务调用,也不可能只有一个暴露接口,所以抽取出来,供其他服务调用与使用。
1、建Module
右键项目--New--Module,选择Maven项目,点击Next,选择父工程,输入模块名称,点击Finish
2、改pom.xml文件
添加刚才新建的公共模块依赖
<dependencies> <!--公共模块依赖--> <dependency> <groupId>com.shiory</groupId> <artifactId>cloud-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
3、编写声明式接口
新建一个接口,加上注解@FeignClient(contextId = "上下文Id", value = "服务提供者服务名称")
注意:
1、方法上加请求方式和接口完整路径(例如此处的@GetMapping("/demo1/api/callTest"))。
2、形参一定要加注解(例如此处的@RequestParam注解)
3、声明式接口与服务提供者暴露的接口必须一致
/** * ===================================================== * 声明式接口开发 * @author 汐小旅Shiory * @date 2021/12/5 22:38 * ===================================================== */ @Component @FeignClient( contextId = "demo1Api", // 上下文Id,保证唯一 value = ServiceNameConstants.CLOUD_DEMO1_SERVICE) // 服务名称(服务提供者的服务名称) public interface Demo1API { @GetMapping("/demo1/api/callTest") public String callTest(@RequestParam(name = "serverName") String serverName); }
如果请求路径有共同部分,也可以将共有路径抽取出来,在接口上加上@RequestMapping("/demo1/api")注解。可以写成如下形式
import com.shiory.common.constants.ServiceNameConstants; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * ===================================================== * 声明式接口开发 * @author 汐小旅Shiory * @date 2021/12/5 22:38 * ===================================================== */ @Component @FeignClient( contextId = "demo1Api", // 上下文Id,保证唯一 value = ServiceNameConstants.CLOUD_DEMO1_SERVICE) // 服务名称(服务提供者的服务名称) @RequestMapping("/demo1/api") public interface Demo1API { @GetMapping("/callTest") public String callTest(@RequestParam(name = "serverName") String serverName); }
其中服务名称常量ServiceNameConstants如下
/** * ===================================================== * 服务名称常量 * @author 汐小旅Shiory * @date 2021/12/5 22:43 * ===================================================== */ public interface ServiceNameConstants { /** * cloud-demo1服务名称 */ String CLOUD_DEMO1_SERVICE = "cloud-demo1"; }
声明式接口与服务提供者暴露的接口必须一致
4、项目结构
5、 搭建服务消费者:cloud-demo3
1、建Module
右键项目--New--Module,选择Maven项目,点击Next,选择父工程,输入模块名称,点击Finish
2、改pom.xml文件
添加刚才新建的公共模块依赖,公共声明式接口模块依赖
<dependencies> <!--公共模块依赖--> <dependency> <groupId>com.shiory</groupId> <artifactId>cloud-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--公共声明式接口模块依赖--> <dependency> <groupId>com.shiory</groupId> <artifactId>cloud-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
3、新建application.yml文件
在resources目录下新建application.yml文件,并且添加服务名和端口,每个模块的服务名和端口必须保证唯一
server: port: 7003 # 服务端口号,必须配置,保证唯一 spring: application: name: cloud-demo3 # 服务名称,必须配置,保证唯一
4、新建主启动类
在src/main/java中新建一个启动类,添加注解@EnableFeignClients(basePackages = "声明式接口包(cloud-api模块)"),和cloud-common一样,把启动类建在同一级目录一下,比如cloud-common的在com.shiory包下,那这个启动类就建在cloud-demo3的com.shiory包下
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; /** * ===================================================== * 服务消费者 * @author 汐小旅Shiory * @date 2021/12/5 23:13 * ===================================================== */ @SpringBootApplication @EnableFeignClients(basePackages = "com.shiory.api") // 开启openfeign,并扫描声明式接口包 public class Demo3Application { public static void main(String[] args) { SpringApplication.run(Demo3Application.class, args); } }
5、编写Controller
编写controller,并注入声明式接口,就可以像普通接口调用一样进行远程调用
import com.shiory.api.Demo1API; 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.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; /** * ===================================================== * * @author 汐小旅Shiory * @date 2021/12/5 23:14 * ===================================================== */ @RestController @RequestMapping("/demo3") public class Demo3Controller { // 注入声明式接口 @Autowired private Demo1API demo1API; @Value("${spring.application.name}") private String serverName; /** * 使用openfeign发起远程调用 * @return */ @GetMapping("/remoteCall") public Map<String,Object> remoteCall() { // 发起远程调用 String remoteResult = demo1API.callTest(serverName); Map<String, Object> map = new HashMap<>(); map.put("remarks", "我是" + serverName + "服务,正在使用openfeign调用!"); map.put("remoteResult", remoteResult); return map; } }
6、项目结构
6、 测试
1、启动Nacos
2、启动服务提供者cloud-demo1,以及服务消费者cloud-demo3
3、查看服务是否注册到Nacos
4、发起请求(请求cloud-demo3中的接口,cloud-demo3接口中远程调用cloud-demo1中的接口)
7、 小结
1、服务注册与发现(Nacos)
1.1、搭建nacos服务:Windows下搭建Nacos服务
1.2、pom.xml中添加依赖
<!--Nacos场景依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
1.3、application.yml中配置nacos连接信息
spring: cloud: nacos: discovery: server-addr: localhost:8848 # nacos-server的地址 username: nacos # nacos-server用户名 password: nacos # nacos-server密码
1.4、启动类上加注解,开启服务注册与发现
@EnableDiscoveryClient // 服务注册与发现
2、远程调用(openfeign)
2.1、pom.xml中添加依赖
<!--openfeign场景依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
2.2、服务提供者
2.2.1、暴露接口
2.2.2、声明式接口开发,接口上使用注解:@FeignClient(contextId = "上下文Id", value = "服务提供者服务名称")
2.3、服务消费者
2.3.1、启动类上加注解:@EnableFeignClients(basePackages = "声明式接口包")
2.3.2、注入声明式接口,发起远程调用