一、整合过程
在项目添加依赖:添加位置
<!--服务调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在需要的服务中添加启动注解:
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
//@MapperScan("com.atguigu.srb.core.mapper")
@ComponentScan({"com.atguigu.common","com.atguigu.srb.sms","com.atguigu.srb.base"})
@EnableDiscoveryClient
@EnableFeignClients //服务远程调用
public class ServiceSmsApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceSmsApplication.class,args);
}
}
并且在该服务创建远程调用接口:
@FeignClient(value = "service-core") //调用的远程服务名
@RequestMapping("/api/core/userInfo") //该请求路径必须与需要远程调用方法的请求路径一致
public interface CoreUserInfoClient {
@GetMapping("isMobileExist/{mobile}")
public boolean isMobileExist(@PathVariable String mobile);
}
对比图:
在service-core服务中实现被调用的远程方法:
service层:
/**
* <p>
* 用户基本信息 服务类
* </p>
*
* @author Helen
* @since 2023-04-06
*/
public interface UserInfoService extends IService<UserInfo> {
void register(RegisterVO registerVO);
UserInfoVO login(LoginVO loginVO, String ip);
boolean isMobileExist(String mobile);
}
serviceImpl层:
/**
* <p>
* 用户基本信息 服务实现类
* </p>
*
* @author Helen
* @since 2023-04-06
*/
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
@Autowired
RedisTemplate redisTemplate;
@Autowired
UserAccountMapper userAccountMapper;
@Autowired
UserLoginRecordMapper userLoginRecordMapper;
@Override
public boolean isMobileExist(String mobile) {
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mobile", mobile);
Integer integer = baseMapper.selectCount(queryWrapper);
if(integer > 0){
return true;
}
return false;
}
}
在service-sms服务中使用远程方法:
@RestController
@RequestMapping("/api/sms")
@CrossOrigin
public class ApiSmsController {
@Autowired
SmsService smsService;
@Autowired
CoreUserInfoClient coreUserInfoClient;
@GetMapping("sendCode/{mobile}")
public R sendCode(@PathVariable String mobile){
// 先检查手机号是否被注册过
// 调用的是远程serviceImpl的isMobileExist的方法
boolean mobileExist = coreUserInfoClient.isMobileExist(mobile);
// 如果不为false,MOBILE_EXIST_ERROR(207, "手机号已被注册")
Assert.isTrue(!mobileExist, ResponseEnum.MOBILE_EXIST_ERROR);
smsService.sendCode(mobile);
return R.ok();
}
}
二、OpenFiegn整合Sentinel实现兜底方法
在guigu-common微服务添加依赖:
<!--服务容错-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
在service-sms微服务
添加sentinel配置:
spring:
profiles:
active: dev # 环境设置
application:
name: service-sms # 服务名
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# sentinel
sentinel:
transport:
dashboard: localhost:8080
port: 8719
开启被动降级:
feign:
client:
config:
default:
connect-timeout: 600000
read-timeout: 600000
sentinel:
enabled: true # OpenFeign整合sentinel,启动被动降级
开启兜底方案fallback
@FeignClient(value = "service-core",fallback = CoreUserInfoClientFallback.class) //调用的远程服务名,fallback是兜底方案
//@RequestMapping("/api/core/userInfo") 不能放这,会报重复出现的异常
public interface CoreUserInfoClient {
//该请求路径必须与需要远程调用方法的请求路径一致
@GetMapping("/api/core/userInfo/isMobileExist/{mobile}")
public boolean isMobileExist(@PathVariable String mobile);
}
实现兜底方法:
@Component
public class CoreUserInfoClientFallback implements CoreUserInfoClient{
@Override
public boolean isMobileExist(String mobile) {
System.out.println("兜底函数,默认返回手机号已经被注册过");
return true;
}
}