OpenFeign简介
作为Spring Cloud的子项目之一,Spring Cloud OpenFeign 是一种声明式、模板化的 HTTP 客 户端,在 Spring Cloud 中使用 OpenFeign,可以做到使用 HTTP请求远程服务时能与调用本地 方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个 HTTP 请求。同时 OpenFeign通过集成Ribbon实现客户端的负载均衡
nacos-server : 注册中心,解决是服务的注册与发现
Ribbon:客户端负载均衡器,解决的是服务集群负载均衡的问题
OpenFeign:声明式 HTTP 客户端 、代替Resttemplate组件,实现远程调用
2 演示案例说明
cloud-order为服务消费者、cloud-jifen为服务提供者
功能1:添加订单,生成一条积分记录
功能2:修改订单,修改积分记录
功能3:删除订单,删除积分记录
功能4:查询订单,获取积分记录
2.1 新建积分微服务cloud-jifen
编辑pom文件
<dependencies>
<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>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
//依赖其他模块
<dependency>
<groupId>com.qf</groupId>
<artifactId>cloud-entity</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
准备配置文件
spring:
application:
name: cloud-jifen #服务名称,必须,唯一
cloud:
nacos:
discovery:
server-addr: localhost:8848 #指定nacos-server的地址
username: nacos
password: nacos
namespace: sit
group: my-group
server:
port: 9004 #端口号
准备启动类
package com.qf;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class JifenApp {
public static void main(String[] args) {
SpringApplication.run(JifenApp.class, args);
}
}
启动测试,nacos服务列表是否有该服务
2.2 入门案例
在cloud-jifen写controller
package com.qf.controller;
import com.qf.Jifen;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/jifen")
public class JifenController {
@PostMapping(value = "/save")
public Map save(@RequestBody Jifen jifen) {
System.out.println("调用了积分保存接口");
System.out.println(jifen);
return new HashMap() {{
put("isSuccess", true);
put("msg", "save success");
}};
}
@PostMapping(value = "/update")
public Map update(@RequestBody Jifen jifen) {
System.out.println(jifen);
return new HashMap() {{
put("isSuccess", true);
put("msg", "update success");
}};
}
@GetMapping(value = "/delete")
public Map deleteById(Integer jifenId) {
System.out.println("删除id为" + jifenId + "的积分信息");
return new HashMap() {{
put("isSuccess", true);
put("msg", "delete success");
}};
}
@GetMapping(value = "/{jifenId}")
public Jifen findJifenById(@PathVariable Integer jifenId) {
System.out.println("已经查询到" + jifenId + "积分数据");
return new Jifen(jifenId, 12, jifenId + "号积分");
}
@GetMapping(value = "/search")
public Jifen search(Integer uid, String type) {
System.out.println("uid:" + uid + "type:" + type);
return new Jifen(uid, 12, type);
}
@PostMapping(value = "/searchByEntity")
public List<Jifen> searchMap(@RequestBody Jifen jifen) {
System.out.println(jifen);
List<Jifen> jifens = new ArrayList<Jifen>();
jifens.add(new Jifen(110, 12, "下单积分"));
jifens.add(new Jifen(111, 18, "支付积分"));
return jifens;
}
/*@Data
@AllArgsConstructor
@NoArgsConstructor
public class Goods {
private Integer id;
private String goodsName;
}*/
}
在cloud-entity中写实体类Jifen
package com.qf;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Jifen {
private Integer jifenId;
private Integer count;
private String type;
}
在cloud-entity中写实体类Order
package com.qf;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
private Integer uid;
private Integer num;
private String type;
}
在cloud-entity中写实体类ResultVo
package com.qf;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultVo {
private boolean success;
private String msg;
}
在cloud-order里远程调用
第一步:注释RestTemplate
注释掉启动类的RestTemplate
第二步:注释OrderController
注释里面的方法
第三步:添加依赖
在cloud-order中
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
第四步:开启openfeign
添加注解,在cloud-order的启动类上加
@EnableFeignClients //开启openfeign
第五步声明接口
新建一个module,cloud-api
A 添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.qf</groupId>
<artifactId>cloud-entity</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
B 在cloud-api中新建一个接口 JifenApi
@FeignClient("cloud-jifen") //cloud-jifen服务名称
这个注解将由@EnableFeignClients扫描,然后将要远程调用的接口方法去掉方法体复制过来即可。
package com.api;
import com.qf.Jifen;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Map;
@FeignClient("cloud-jifen") //cloud-jifen服务名称
@RequestMapping("/jifen")
public interface JifenApi {
@PostMapping(value = "/save")
public Map save(@RequestBody Jifen jifen);
}
注:形参要加注解@RequestParam("jifenId"),例如:
@GetMapping(value = "/delete")
public Map deleteById(@RequestParam("jifenId") Integer jifenId) ;
第六步扫描openfeign接口
A 在order模块,添加cloud-api的依赖
<dependency>
<groupId>com.qf</groupId>
<artifactId>cloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
B 在启动类,@EnableFeignClients 上添加属性,扫描对应的包
@EnableFeignClients(basePackages = {"com.api"})
第七步远程调用
在ordercontroller中
@Autowired
private JifenApi jifenApi;
@RequestMapping("test1")
public Map test1() {
//通过openfeign远程调用cloud-jifen服务的 /jifen/save
Jifen jifen = new Jifen(1,10,"1");
//url: http://cloud-jifen/jifen/save
Map save = jifenApi.save(jifen);
return save;
}
第八步测试
启动jifen和order,访问地址看是否成功
http://localhost:9002/order/test1
3 openfeign常用配置
#ribbon eager-load 饥饿加载,默认false,表示项目启动时不会强行拉取nacos实例列表,而是第一次发请求的时候拉取。true表示当项目启动立即拉取实例列表
#clients 表示当项目启动时,立即饥饿加载 cloud-jifen 和 cloud-goods 的实例列表
ribbon:
eager-load:
enabled: true
clients:
- cloud-jifen
- cloud-goods
#feign
#feign:
# client:
# config:
# cloud-jifen:
# connectTimeout: 1000 #建立连接1秒
# readTimeout: 1 #响应时间,设置cloud-jifen 相应的超时时间为1毫秒
# default: #其他的服务建立时间与响应时间
# connectTimeout: 1000
# readTimeout: 1