因为Spring Cloud Feign是基于Http Restful的调用,在高并发下的性能不够理想(虽然他是基于Ribbon以及带有熔断机制,可以防止雪崩),成为性能瓶颈,所以我们今天对Feign进行Dubbo的RPC改造。
我们Spring Cloud的项目结构如下
其中user-center是我们的用户中心,game-center是我们的游戏中心,以游戏中心调用用户中心的Feign如下
@Component@FeignClient("user-center")public interface UserClient { @PutMapping("/api-u/users-anon/internal/updateAppUser") AppUser updateUser(@RequestBody AppUser appUser); @PostMapping("/api-u/users-anon/internal/users/updateUserBanlance") String updateUserBanlance(@RequestParam("id") long id, @RequestParam("banlance") BigDecimal banlance);}
我们先来改造用户中心作为Dubbo的提供者,pom添加Dubbo的引用
com.alibaba.spring.boot dubbo-spring-boot-starter 2.0.0 com.github.sgroschupf zkclient 0.1
将service接口放入公共模块api-model
public interface AppUserService { void addTestUser(AppUser user); void addAppUser(AppUser appUser); void updateAppUser(AppUser appUser); LoginAppUser findByUsername(String username); AppUser findById(Long id); void setRoleToUser(Long id, SetroleIds); void updatePassword(Long id, String oldPassword, String newPassword); void updateWithdrawal(Long id, String oldPassword, String newPassword); Page findUsers(Map params); Set findRolesByUserId(Long userId); void bindingPhone(Long userId, String phone); int updateUserBanlance(long id, BigDecimal banlance); Map findUserMapById(long userId); Page
用户中心资源配置,添加dubbo配置
spring: application: name: user-center cloud: config: discovery: enabled: true serviceId: config-center profile: dev dubbo: application: id: user-center-dubbo-prodiver name: user-center-dubbo-prodiver registry: address: zookeeper://192.168.5.129:2181 server: true protocol: name: dubbo port: 20880
接口实现类的标签修改
@Slf4j@Service(interfaceClass = AppUserService.class)@Componentpublic class AppUserServiceImpl implements AppUserService {
其中这个@Service已经不再是spring的标签,而需要使用,
import com.alibaba.dubbo.config.annotation.Service;
的Dubbo标签
之前的spring @Service改用
在Springboot的主类添加Dubbo的配置标签
@EnableDubboConfiguration@EnableScheduling@EnableSwagger2@EnableFeignClients@EnableDiscoveryClient@SpringBootApplicationpublic class UserCenterApplication { public static void main(String[] args) { SpringApplication.run(UserCenterApplication.class, args); }}
此时启动用户中心项目,可以在Dubbo主控台中看到
点进去可以看到提供者注册信息
然后再来看看游戏中心的消费者
pom依赖跟用户中心一样
资源文件配置添加Dubbo配置
spring: application: name: game-center cloud: config: discovery: enabled: true serviceId: config-center profile: dev dubbo: application: name: game-center-dubbo-consumer id: game-center-dubbo-consumer protocol: port: 20800 name: dubbo registry: address: zookeeper://192.168.5.129:2181
在使用的Controller中注释掉之前的feign注入,使用Dubbo的接口
// @Autowired// private UserClient userClient;
@Referenceprivate AppUserService appUserService;
因为该接口在公共模块api-model中,所以任何模块都可以识别的到,此时需要使用Dubbo的注释
import com.alibaba.dubbo.config.annotation.Reference;
在Springboot主类中添加Dubbo注释
@EnableDubboConfiguration@EnableScheduling@EnableSwagger2@EnableFeignClients@EnableDiscoveryClient@SpringBootApplicationpublic class GameCenterApplication { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(GameCenterApplication.class, args); SpringBootUtil.setApplicationContext(context); }}
启动游戏中心项目,在Dubbo控制台中的消费者中,我们可以看到
点进去可以看到消费者注册信息
这样我们在实际使用中,将之前的feign代码改成直接使用该service接口就可以通过RPC的远程调用了
//调用userService更新用户信息 TODO// userClient.updateUser(user); appUserService.addAppUser(user);
最后就是进行压测,性能要绝对优于Feign调用的吞吐量。