• Spring Cloud+Dubbo对Feign进行RPC改造



    因为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的引用

    <dependency>
       <groupId>com.alibaba.spring.boot</groupId>
       <artifactId>dubbo-spring-boot-starter</artifactId>
       <version>2.0.0</version>
    </dependency>
    <dependency>
       <groupId>com.github.sgroschupf</groupId>
       <artifactId>zkclient</artifactId>
       <version>0.1</version>
    </dependency>

    将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, Set<Long> roleIds);
    
       void updatePassword(Long id, String oldPassword, String newPassword);
    
       void updateWithdrawal(Long id, String oldPassword, String newPassword);
    
       Page<AppUser> findUsers(Map<String, Object> params);
    
       Set<SysRole> findRolesByUserId(Long userId);
    
       void bindingPhone(Long userId, String phone);
    
       int updateUserBanlance(long id, BigDecimal banlance);
    
       Map<String, Object> findUserMapById(long userId);
    
       Page<Map<String, Object>> findUsers(String username, BigDecimal minBanlance, BigDecimal maxBanlance, String startTime, String endTime, Integer groupId, Integer control, int pageNo, int pageSize);
    
       void deleteTestUser(Assist assist);
    }

    用户中心资源配置,添加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)
    @Component
    public class AppUserServiceImpl implements AppUserService {

    其中这个@Service已经不再是spring的标签,而需要使用,

    import com.alibaba.dubbo.config.annotation.Service;

    的Dubbo标签

    之前的spring @Service改用@Component

    在Springboot的主类添加Dubbo的配置标签

    @EnableDubboConfiguration
    @EnableScheduling
    @EnableSwagger2
    @EnableFeignClients
    @EnableDiscoveryClient
    @SpringBootApplication
    public 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;
    @Reference
    private AppUserService appUserService;

    因为该接口在公共模块api-model中,所以任何模块都可以识别的到,此时需要使用Dubbo的注释

    import com.alibaba.dubbo.config.annotation.Reference;

    在Springboot主类中添加Dubbo注释

    @EnableDubboConfiguration
    @EnableScheduling
    @EnableSwagger2
    @EnableFeignClients
    @EnableDiscoveryClient
    @SpringBootApplication
    public 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调用的吞吐量。


     转载至链接:https://my.oschina.net/u/3768341/blog/2395878。
  • 相关阅读:
    Go语言TCP/UDP Socket编程
    Go目录
    Go语言获取项目当前路径
    Mysql写入记录出现 Incorrect string value: 'xB4xE7xB1xCAxBCxC7‘错误?(写入中文)
    Erlang的Web库和框架
    erlang 资源
    Erlang基础2
    Erlang语言基础总结
    angular修改端口号port
    npm ERR! Cannot read property 'resolve' of undefined
  • 原文地址:https://www.cnblogs.com/lykbk/p/asdasfasdw3432423e.html
Copyright © 2020-2023  润新知