勿以浮沙筑高台
建立项目
- 项目结构如下图
springcloud最外层引入依赖项
springquickstart继承自springcloud,并引入相同依赖<properties> <java.version>1.8</java.version> <!--定义springboot和springcloud的版本--> <spring-boot.version>2.2.13.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR10</spring-cloud.version> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies>
erueka-server服务搭建
需要继承自quickstart项目
<parent>
<artifactId>springcloud-quickstart</artifactId>
<groupId>org.example</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
- 引入依赖springboot-web和springcloud-eureka-server
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
- 项目结构
创建服务启动类配置注解@EnableEurekaServer 代表为启动服务的入口@SpringBootApplication @EnableEurekaServer // 启动eureka服务 public class EurekaServerApplication { public static void main(String[] args) { //启动当前自己类 SpringApplication.run(EurekaServerApplication.class, args); } }
- 配置application.yml文件
server: port: 18671 eureka: instance: hostname: localhost client: #registerWithEureka: false #fetchRegistry: false fetch-registry: false # //表示是否将自己注册到Eureka Server, register-with-eureka: false # //表示是否从Eureka Server集群获取注册的服务信息 service-url: #//定义的默认中心的地址,代表localhost:18671/eureka/ defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
- 启动项目
访问端口localhost:18671
出现这个界面就代表成功
erueka-provider调用转发者搭建
- 引入Maven
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--引入eureka client的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--引入Spring CLoud 的 ribbon组件--> <!--引入客户端负载均衡组件--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-ribbon</artifactId> </dependency> <!--引入公共实体模块--> <dependency> <groupId>org.example</groupId> <artifactId>common</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies>
- application.yml配置
server: port: 10206 spring: application: name: common-provider eureka: client: service-url: defaultZone: http://localhost:18671/eureka/ #erueka地址 instance: prefer-ip-address: false #这里代表是否用ip注入,这里选择false,用false在12版本中选择false代表可以用服务名称访问
- 项目结构
- 代码编写
StockClientImpl
RestConfig@Service public class StockClientImpl implements StockClient { @Autowired private RestTemplate restTemplate; @Override public CommonResult reduceStock(User vo) { //COMMON-CONSUMER:请求的服务名称 //test/index:方法路径 //这里进行请求的转发等待返回值。 String uri = String.format("http://COMMON-CONSUMER/%s","test/index"); return restTemplate.postForObject(uri,vo, CommonResult.class); } }
Provider@SpringBootConfiguration public class RestConfig { @Bean // 手动装配RestTemplate到IOC容器中 @LoadBalanced // 使用负载均衡的方式创建Rest请求模板对象 public RestTemplate restTemplate() { return new RestTemplate(); } }
@RestController public class Provider { @Autowired(required = false) private StockClient stockClient; @PostMapping("/save") public void Save(@RequestBody User user){ CommonResult result = stockClient.reduceStock(user); if (result.getCode() == 201) { throw new RuntimeException("远程调用库存服务出现问题...."); } System.out.println(user.toString()); } }
- 在eureka中查看,出现服务名称则注册成功
erueka-provider消费者搭建
- 项目结构
- application.yml配置文件
server: port: 10101 spring: application: name: common-consumer eureka: client: service-url: defaultZone: http://localhost:18671/eureka/ instance: prefer-ip-address: false
- 代码编写
@RestController @RequestMapping("test") public class Consumer { @PostMapping(value = "/index") public CommonResult index(@RequestBody User user) { System.out.println("这里是Consumer流程" + user.toString()); return CommonResult.OK(); } }
- 在eureka中查看,出现服务名称则注册成功
测试
通过提供者进行转发,返回200成功。
consumer接受到了请求,成功
代码:
link:https://pan.baidu.com/s/1maKwnS_bd6GMx_wL780gRg
password:6olp
在我们使用ribbon时发现有强耦合代码每个类都要注入resttemplate,并指明请求的服务地址。地址和代码强耦合在了一起,这时我们用openfegin来做客户端的负载均衡解耦。
1.因为openfegin是转发的主动提供接口,因此单独提供一个api项目
2.引入maven
<dependencies>
<!--引入公共类-->
<dependency>
<groupId>org.example</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--引入openfegin-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
3.编写接口
@Component
@RequestMapping("test")
@FeignClient("common-consumer")
public interface ConsumerAPI {
@PostMapping(value = "/index")
//这个接口务必和服务提供接口一直。
CommonResult openfegin(@RequestBody User user);
}
3.在转发服务中引用api项目
<dependency>
<groupId>org.example</groupId>
<artifactId>common-consumer-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
4.service中调用
@Autowired(required = false)
private ConsumerAPI consumerAPI;
@PostMapping("/openfegin")
public void openfegin(@RequestBody User user){
CommonResult result = consumerAPI.openfegin(user);
if (result.getCode() == 201) {
throw new RuntimeException("远程调用库存服务出现问题....");
}
System.out.println(user.toString());
}
调用测试。成功!
代码:
https://pan.baidu.com/s/1Odd3UhETiWy1ESU_1E-_hA
pwd:twbs