目录
1.3.2、 编辑sca-consumer的pom.xml文件,创建并修改配置文件application.yml
1.3.3、 编辑sca-gateway的pom.xml文件
1.3.4、 编辑sca-provider的pom.xml文件,创建并修改配置文件application.yml
2.4.1、 在sca-provider下面创建测试类,启动类和controller类
2.4.3、 在sca-consumer下面创建启动类和controller类
3.2、 创建RemoteProviderService接口
3.3、 创建用于远程调用的FeignConsumerController类
1、聚合项目
1.1、 新建项目初始化配置
1.1.1、新建一个空项目
1.1.2、 初始化配置maven
1.1.3、 初始化配置jdk
配置编译环境
jdk编译版本选择8
1.1.4、 初始化配置编码
1.2、 创建聚合父工程和子工程
1.2.1、创建聚合父工程
1.2.2、 删除此工程下的src目录,父工程不需要此目录
1.2.3、 修改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">
<artifactId>01-sca</artifactId>
<!-- 父工程默认打包方式pom方式,创建此工程的子工程时会默认添加这个配置-->
<packaging>pom</packaging>
<!-- 创建此工程的子工程时默认会创建这个配置
在这个元素内部会定义当前项目下的一些模块
当对父工程进行编译打包时,会对modules元素
内部定义的子工程进行同样的编译和打包
-->
<modules>
<module>sca-provider</module>
<!-- provider服务提供方③ -->
<module>sca-consumer</module>
<!-- consumer服务消费方②-->
<module>sca-gateway</module>
<module>sca-common</module>
<!-- sca-gateway网关服务①-->
</modules>
<groupId>com.jt</groupId>
<version>1.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<!--maven的父工程中的dependencyManagement主要负责定义依赖版本管理-->
<dependencyManagement>
<dependencies>
<!--Spring Boot 依赖(此依赖中定义了springboot工程核心依赖的版本)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.2.RELEASE</version>
<scope>import</scope>
<type>pom</type> <!--只有类型为pom的才可以import-->
</dependency>
<!--Spring Cloud 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 定义子工程中都需要的依赖-->
<dependencies>
<!-- lombok依赖 子工程中假如需要它,不需要再引入-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<!-- 表示此以来仅在编译阶段-->
</dependency>
<!--单元测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!-- test 表示只能在test目录下使用次依赖-->
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</exclusion>
<!-- 排除不需要的依赖-->
</exclusions>
</dependency>
</dependencies>
<!-- 定义当前工程模块及子工程都会采用此版本编译-->
<!-- 项目构建配置,我们基于maven完成项目的编译测试打包等操作,
都是基于pom.xml完成这一系列的操作,但是编译和打包的配置都是需要手写到build元素内的
而具体的编译和打包配置又需要plugin去实现,plugin元素不是必须的,maven有默认的plugin的配置
-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
1.2.4、 创建子工程模块
1.3、 配置部署项目
1.3.1、 编辑sca-common的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">
<parent>
<artifactId>01-sca</artifactId>
<groupId>com.jt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>sca-common</artifactId>
</project>
1.3.2、 编辑sca-consumer的pom.xml文件,创建并修改配置文件application.yml
<?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">
<parent>
<artifactId>01-sca</artifactId>
<groupId>com.jt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.jt</groupId>
<artifactId>sca-consumer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.1</version>
</dependency>
</dependencies>
</project>
server:
port: 8090
spring:
application:
name: sca-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
1.3.3、 编辑sca-gateway的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">
<parent>
<artifactId>01-sca</artifactId>
<groupId>com.jt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.jt</groupId>
<artifactId>sca-gateway</artifactId>
</project>
1.3.4、 编辑sca-provider的pom.xml文件,创建并修改配置文件application.yml
<?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">
<parent>
<artifactId>01-sca</artifactId>
<groupId>com.jt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.jt</groupId>
<artifactId>sca-provider</artifactId>
<!-- 引用common工程的资源-->
<dependencies>
<!--Web服务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--服务的注册和发现(我们要讲服务注册到nacos)-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.1</version>
</dependency>
<dependency>
<groupId>com.jt</groupId>
<artifactId>sca-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
server:
port: 8081
spring:
application:
name: sca-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848
2、 Nacos服务注册
2.1、 数据库启动
最好使用mysql5.7版本以上或者mariadb10.5以上版本,低版本数据库在后面操作nacos可能会出现很多报错。
2.2、 nacos安装配置启动
下载nacos选择合适的版本
数据登录之后 执行脚本文件
格式:source +路径+ nacos-mysql.sql
source D:/nacos/nacos-mysql.sql
打开/conf/application.properties里打开默认配置
2.3、 服务启动与访问
win10系统启动,在nacos的bin目录的cmd中输入下面代码进行启动
startup.cmd -m standalone
启动成功如图
打开浏览器,输入 http://localhost:8848/nacos 地址 账号密码一样 nacos
2.4、 测试调试
2.4.1、 在sca-provider下面创建测试类,启动类和controller类
编辑test类
package com.jt.common;
import com.jt.common.util.StringUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
//这个注解描述的类为stringboot工程的单元测试类
@SpringBootTest
//@SpringBootConfiguration //没有启动类时可以使用此注解进行测试
public class StringTests {
/*
* 在当前得到测试类方法中使用了sca-common下面中的StringUtils工具类
* */
@Test//使用这个注解下面的就默认是public修饰
void testStringEmpty(){
String content="helloworld";//flase
boolean flag = StringUtils.isEmpty(content);
System.out.println(flag);//null时为true
}
}
创建启动类
package com.jt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProviderAppRun {
public static void main(String[] args) {
SpringApplication.run(ProviderAppRun.class,args);
}
}
编辑controller类
package com.jt.provider.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
//创建一个服务提供方对象 通过此对象处理服务消费端请求
@RestController
public class ProviderController {
@Value("${server.port:8081}")
private String server;
@Value("${spring.application.name: sca-provider}")
private String spring;
//请求处理对象是通过方法处理客户端或者服务消费端请求
//当前方法主要用于实现一个字符串回显,就是向客户端或服务消费端返回一个字符串消息
@GetMapping("/provider/echo/{msg}")
public String doRestEcho01(@PathVariable String msg){
return server+"-"+spring+ "-say Hello-"+msg;
}
}
2.4.2、 在sca-common下面创建工具类
编辑util文件
package com.jt.common.util;
/**
定义一个操作字符串工具类
str就是要验证的字符串
判断字符串是否为空return为true则为空
**/
public class StringUtils {
public static boolean isEmpty(String str){
return str==null||"".equals(str);
}
}
2.4.3、 在sca-consumer下面创建启动类和controller类
编辑controller类
package com.jt.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.RestController;
import org.springframework.web.client.RestTemplate;
//定义服务消费端Controller,在这个Controller对象的方法中实现对远端的sca-provider的调用
@RestController
public class ConsumerController {
//从spring容器获取一个RestTemplate对象,基于此对象进行远端调用
@Autowired
private RestTemplate restTemplate;//spring框架中没有配置这个东西 需要手动配置 所以在启动类中(配置类)
@Value("${spring.application.name:appName}")
private String appName;
@GetMapping("/consumer/doRestEch01")
public String doRestEcho01(){
// 1.定义要调用的远端服务的URL
String url="http://localhost:8081/provider/echo/"+appName;
// 2.基于RestTemplate对象的相关方法进行服务调用
return restTemplate.getForObject(url,String.class );
}}
创建启动类
package com.jt.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableFeignClients
//使用@EnableFeignClients注解描述配置类时,主要用于告诉spring框架,
//要对使用@FeignClient注解描述的接口创建其实现类和对象.
public class ConsumerApplicationRun {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplicationRun.class,args);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
/**
* 假如@LoadBalanced注解描述RestTemplate对象时,
* 假如使用RestTemplate对象发起远程服务调用,底层会对这个请求
* 进行拦截,拦截到此请求后,会基于LoadBalancedClient对象
* 获取服务实例后,然后进行负载均衡的方式进行调用
* @return
* */
@Bean
@LoadBalanced
public RestTemplate loadBalancedRestTemplate() {
return new RestTemplate();
}
}
2.4.4、 效果展示
关闭服务器五秒钟后
三十秒之后默认彻底死掉
3、 负载均衡和简化操作
3.1、 编辑consumer的controller类
/**
* 目标:在doRestEcho01的基础之上实现负载均衡?
* 如何:LoadBalancerClient
*/
//LoadBalancerClient对象负责从nacos服务中发现和获取服务实例
@Autowired
private LoadBalancerClient loadBalancerClient;//RibbonLoadBalancerClient
@GetMapping("/consumer/doRestEcho02")
public String doRestEcho02(){
//1.获取provider服务实例
ServiceInstance serviceInstance =
//sca-provider 为nacos服务列表中的服务名
loadBalancerClient.choose("sca-provider");
String host=serviceInstance.getHost();
int port=serviceInstance.getPort();
//2.定义要调用的远端服务的url
//String url="http://"+host+":"+port+"/provider/echo/"+appName;
String url = String.format("http://%s:%s/provider/echo/%s",
host,port,appName);
//3.基于restTemplate对象中的相关方法进行服务调用
return restTemplate.getForObject(url, String.class);
}
/*目标:在doRestEcho03方法中对doRestEcho02代码实现简化操作
*简化:简化基于loadBalancerClient获取服务实例信息的过程
*如何简化的?底层为RestTemplate对象注入拦截器,在底层拦截器中实现服务实例的获取.
*如何为RestTemplate对象注入拦截器?RestTemplate对象构建时使用@LoadBalanced注解进行描述
*/
@Autowired
private RestTemplate loadBalancedRestTemplate;
@GetMapping("/consumer/doRestEcho03")
public String doRestEcho03(){
String serviceId="sca-provider";//nacos服务列表中的一个服务名
//String url="http://"+serviceId+"/provider/echo/"+appName;
String url=String.format("http://%s/provider/echo/%s",serviceId,appName);
return loadBalancedRestTemplate.getForObject(url,String.class);
}
3.2、 创建RemoteProviderService接口
package com.jt.consumer.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
//@FeignClient注解描述的接口用于定义远程调用规范
//其中@FeignClient的name属性的值为远端服务名。
//同时也会将这个名字作为RemoteProviderService接口实现类的bean对象的名字
@FeignClient(name="sca-provider")
public interface RemoteProviderService {
@GetMapping("/provider/echo/{msg}")
String echoMessage(@PathVariable("msg") String msg);
}
3.3、 创建用于远程调用的FeignConsumerController类
package com.jt.consumer.controller;
import com.jt.consumer.service.RemoteProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/consumer/")
public class FeignConsumerController {
@Autowired
private RemoteProviderService remoteProviderService;
@GetMapping("echo/{msg}")
public String doFeignEcho(@PathVariable("msg") String msg){
return remoteProviderService.echoMessage(msg);
}
}
3.4、 添加consumer的pom.xml中的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
3.5、 效果展示