8288分类目录 8288分类目录 8288分类目录
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

Spring Cloud整合Thrift RPC(二) - spring-cloud-thrift-

来源:本站原创 浏览:41次 时间:2023-05-16
前言

上一篇简单的阐述了 spring-cloud-thrift-starter 这个插件的配置和使用,并引入了一个 calculator的项目。本文将基于一个银行存款、取款的业务场景,给出一套 thrift在生产环境的应用案例。

首先设计如下几张简单的数据库表:银行( bank)、分支( branch)、银行卡( deposit_card)、客户( customer)、存款历史纪录( deposit_history)、取款历史纪录( withdraw_history)。

正文

项目结构如下,依然是由三个模块组成:

  • deposit

  • deposit-client

  • deposit-iface

  • deposit-server
Thrift IDL编写

关于 thrift更复杂的用法可以参考 ApacheThrift基础学习系列,根据数据库表的设计编写 deposit.thrift。

deposit.thrift定义了以下四个部分:命名空间 ( namespace)、枚举类型 ( enum)、结构类型 ( struct)和服务类型 ( service)。

(a). 命名空间 ( namespace)

// 指定编译生成的源代码的包路径名称namespace java com.icekredit.rpc.thrift.examples.thrift

(b). 枚举类型 ( enum)

// 通过枚举定义银行分支所属区域enum ThriftRegion {   NORTH = 1,   CENTRAL = 2,   SOUTH = 3,   EAST = 4,   SOUTHWEST = 5,   NORTHWEST = 6,   NORTHEAST = 7}// 存款完成状态enum ThriftDepositStatus {   FINISHED = 1,   PROCCEDING = 2,   FAILED = 3}// 取款完成状态enum ThriftWithdrawStatus {   FINISHED = 1,   PROCCEDING = 2,   FAILED = 3}

(c). 结构类型 ( struct)

// 银行struct ThriftBank {   1: required i64 id,   2: required string code,   3: required string name,   4: optional string description,   5: optional map<ThriftRegion, list<ThriftBranch>> branches}// 银行分支struct ThriftBranch {   1: required i64 id,   2: required string code,   3: required string name,   4: required string address,   5: optional i32 staffs,   6: optional ThriftBank bank,   7: optional ThriftRegion region}// 客户struct ThriftCustomer {   1: required string IDNumber,   2: required string name,   3: required string birthday,   4: required i32 sex = 0,   5: required i32 age,   6: optional list<string> address,   7: optional set<ThriftDepositCard> depositCards}// 银行卡struct ThriftDepositCard {   1: required string id,   2: required bool isVip,   3: required string openingTime,   4: required double accountBalance,   5: optional double accountFlow,   6: optional ThriftBranch branch,   7: optional ThriftCustomer customer,   8: optional list<ThriftDeposit> depositHistory,   9: optional list<ThriftWithdraw> WithdrawHistory}// 存款历史纪录struct ThriftDeposit {   1: required string serialNumber,   2: required double transactionAmount,   3: required string submittedTime,   4: optional string finishedTime,   5: optional ThriftDepositStatus status,   6: optional ThriftDepositCard depositCard}// 取款历史纪录struct ThriftWithdraw {   1: required string serialNumber,   2: required double transactionAmount,   3: required string submittedTime,   4: optional string finishedTime,   5: optional ThriftWithdrawStatus status,   6: optional ThriftDepositCard depositCard}

(d). 服务类型 ( service)

// 银行 - 业务服务定义service ThriftBankService {   void registerNewBank(ThriftBank bank);   list<ThriftBank> queryAllBanks();   ThriftBank getBankById(i64 bankId);   map<ThriftRegion, list<ThriftBranch>> queryAllBranchesByRegion(i64 bankId);}// 银行分支 - 业务服务定义service ThriftBranchService {   void addNewBranch(i64 bankId, ThriftBranch branch);   list<ThriftBranch> queryAllBranches(i64 bankId);   ThriftBranch getBranchById(i64 branchId);}// 客户 - 业务服务定义service ThriftCustomerService {   ThriftCustomer getCustomerById(string customerId);   list<ThriftCustomer> queryAllCustomers();   void addNewUser(ThriftCustomer customer);   void modifyUserById(string customerId, ThriftCustomer customer);   i32 getTotalDepositCard(string customerId);}// 银行卡 - 业务服务定义service ThriftDepositCardService {   set<ThriftDepositCard> queryAllDepositCards(string customerId);   void addNewDepositCard(string customerId, ThriftDepositCard depositCard);   ThriftDepositStatus depositMoney(string depositCardId, double money);   ThriftWithdrawStatus withdrawMoney(string depositCardId, double money);   list<ThriftDeposit> queryDepositHistorys(string depositCardId);   list<ThriftWithdraw> queryWithdrawHistorys(string depositCardId);}

进入 src/main/thrift目录,编译生成所需的枚举类、结构类和业务服务类的源文件。

thrift -gen java ./deposit.thrift

所有生成的源文件都位于同一个命名空间(包)下面: com.icekredit.rpc.thrift.examples.thrift

中间契约(deposit-iface)

将上述源文件拷贝到 deposit-iface 模块中。

通过 Mybatis逆向工程插件生成 SQLMapper的 XML和接口文件以及实体类。

友情提示: Mybatis逆向工程生成的实体类 ( entity),需要和 Thrift编译生成器生成的结构类 ( struct) 区分开来。而 Thrift生成器生成的所有源文件,都一定程度封装了底层的通信方式和相关协议,开发人员是不应该动手脚的。

为了在 Thrift中通过 Mybatis完成数据持久化,必须在实体类 ( entity)包装一层与结构类 ( struct)相互转换的方法。
在每个实体类中,根据业务添加以下两个方法,以 DepositCard为例:

  • toThrift():将实体类对象转换为结构类对象。
    public ThriftDepositCard toThrift() {        ThriftDepositCard thriftDepositCard = new ThriftDepositCard();        thriftDepositCard.setId(this.getId());        thriftDepositCard.setAccountBalance(this.getAccountBalance());        thriftDepositCard.setAccountFlow(this.getAccountFlow());        thriftDepositCard.setIsVip(this.getIsVip());        thriftDepositCard.setOpeningTime(this.getOpeningTime());        ThriftBranch thriftBranch = new ThriftBranch();        thriftBranch.setId(this.getBranchId());        thriftDepositCard.setBranch(thriftBranch);        ThriftCustomer thriftCustomer = new ThriftCustomer();        thriftCustomer.setIDNumber(this.getCustomerId());        thriftDepositCard.setCustomer(thriftCustomer);        return thriftDepositCard;    }
  • fromThrift():静态方法,将结构类对象转换为实体类对象。
    public static DepositCard fromThrift(ThriftDepositCard thriftDepositCard) {        DepositCard depositCard = new DepositCard();        depositCard.setId(thriftDepositCard.getId());        depositCard.setAccountBalance(thriftDepositCard.getAccountBalance());        depositCard.setAccountFlow(thriftDepositCard.getAccountFlow());        depositCard.setIsVip(thriftDepositCard.isIsVip());        ThriftCustomer thriftCustomer = thriftDepositCard.getCustomer();        if (thriftCustomer != null) {            String customerIDNumber = thriftCustomer.getIDNumber();            depositCard.setCustomerId(customerIDNumber);        }        ThriftBranch thriftBranch = thriftDepositCard.getBranch();        if (thriftBranch != null) {            Long branchId = thriftBranch.getId();            depositCard.setBranchId(branchId);        }        depositCard.setOpeningTime(thriftDepositCard.getOpeningTime());        return depositCard;    }
服务端(deposit-server)

在服务端模块引入:

  • spring-cloud-starter-thrift-server: thrift服务端的 starter程序。

  • calculator-iface:中间契约模块,这里作为服务端骨架( Skeleton)程序。

pom.xml

<parent>    <groupId>com.icekredit.rpc.thrift.examples</groupId>    <artifactId>deposit</artifactId>    <version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>deposit-server</artifactId><packaging>jar</packaging><dependencies>    <!-- Thrift相关依赖 -->    <dependency>        <groupId>com.icekredit.rpc.thrift</groupId>        <artifactId>spring-cloud-starter-thrift-server</artifactId>        <version>1.0-SNAPSHOT</version>    </dependency>    <dependency>        <groupId>com.icekredit.rpc.thrift.examples</groupId>        <artifactId>deposit-iface</artifactId>        <version>1.0-SNAPSHOT</version>    </dependency>    <!-- SpringBoot依赖 -->    <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>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>    </dependency>    <dependency>        <groupId>com.alibaba</groupId>        <artifactId>druid-spring-boot-starter</artifactId>        <version>1.1.5</version>    </dependency>    <dependency>        <groupId>org.mybatis.spring.boot</groupId>        <artifactId>mybatis-spring-boot-starter</artifactId>        <version>1.3.0</version>    </dependency>    <!-- Swagger依赖 -->    <dependency>        <groupId>io.springfox</groupId>        <artifactId>springfox-swagger2</artifactId>        <version>2.6.1</version>    </dependency>    <dependency>        <groupId>io.springfox</groupId>        <artifactId>springfox-swagger-ui</artifactId>        <version>2.6.1</version>    </dependency></dependencies><build>    <plugins>        <plugin>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-maven-plugin</artifactId>        </plugin>    </plugins></build>

在 application.yml中配置 thrift服务端的运行参数、数据源连接池参数和 Mybatis相关属性:

application.yml

server:  port: 8080endpoints:  actuator:    sensitive: false    enabled: truemanagement:  security:    enabled: falsespring:  datasource:    druid:      url: jdbc:mysql://localhost:3306/deposit?useUnicode=true&characterEncoding=utf-8      driver-class-name: com.mysql.jdbc.Driver      username: root      password: root  thrift:    server:      service-id: deposit-server-rpc      service-model: hsHa      port: 25000      worker-queue-capacity: 1000      hs-ha:        min-worker-threads: 5        max-worker-threads: 20        keep-alived-time: 3mybatis:  mapper-locations: classpath:mapper/*.xml  type-aliases-package: com.icekredit.rpc.thrift.examples.http.entitieslogging:  level:    root: INFO    com:      icekredit:        rpc:          thrift:            examples:              mapper: DEBUG

服务端程序启动入口类,设置 SwaggerAPI所在的包路径名称。

Application.java

@SpringBootApplication@EnableSwagger2public class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }    @Bean    public Docket createRestfulApi() {        return new Docket(DocumentationType.SWAGGER_2)                .apiInfo(apiInfo())                .select()                .apis(RequestHandlerSelectors.basePackage("com.icekredit.rpc.thrift.examples.service.http.controller"))                .paths(PathSelectors.any())                .build();    }    private ApiInfo apiInfo() {        return new ApiInfoBuilder()                .title("Deposit Server")                .description("Deposit Server")                .version("1.0")                .build();    }}

编写服务端的 Thrift的实现,以 ThriftDepositCardService为例,由实现类 ThriftDepositCardServiceImpl实现 ThriftDepositCardService.Iface接口的方法:

ThriftDepositCardServiceImpl.java

@ThriftService(name = "thriftDepositCardService")public class ThriftDepositCardServiceImpl implements ThriftDepositCardService.Iface {    private final BranchMapper branchMapper;    private final DepositCardMapper depositCardMapper;    private final CustomerMapper customerMapper;    private final DepositHistoryMapper depositHistoryMapper;    private final WithdrawHistoryMapper withdrawHistoryMapper;    @Autowired    public ThriftDepositCardServiceImpl(BranchMapper branchMapper, DepositCardMapper depositCardMapper, CustomerMapper customerMapper, DepositHistoryMapper depositHistoryMapper, WithdrawHistoryMapper withdrawHistoryMapper) {        this.branchMapper = branchMapper;        this.depositCardMapper = depositCardMapper;        this.customerMapper = customerMapper;        this.depositHistoryMapper = depositHistoryMapper;        this.withdrawHistoryMapper = withdrawHistoryMapper;    }    @Override    public Set<ThriftDepositCard> queryAllDepositCards(String customerId) throws TException {        List<DepositCard> depositCardList = depositCardMapper.queryAllDepositCards(customerId);        // 查询客户持有的银行卡        return depositCardList.stream().map(depositCard -> {            ThriftDepositCard thriftDepositCard = depositCard.toThrift();            Long branchId = depositCard.getBranchId();            if (Objects.nonNull(branchId) && branchId > 0L) {                Branch branch = branchMapper.findById(branchId);                ThriftBranch thriftBranch = branch.toThrift();                ThriftBank thriftBank = new ThriftBank();                thriftBank.setId(branch.getBankId());                thriftBranch.setBank(thriftBank);                thriftDepositCard.setBranch(thriftBranch);            }            Customer customer = customerMapper.findById(customerId);            ThriftCustomer thriftCustomer = customer.toThrift();            thriftDepositCard.setCustomer(thriftCustomer);            return thriftDepositCard;        }).collect(Collectors.toSet());    }    @Override    @Transactional    public void addNewDepositCard(String customerId, ThriftDepositCard depositCard) throws TException {        DepositCard newDepositCard = DepositCard.fromThrift(depositCard);        // 新增银行卡信息        depositCardMapper.save(newDepositCard);    }    @Override    @Transactional    public ThriftDepositStatus depositMoney(String depositCardId, double money) throws TException {        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        try {            DepositHistory depositHistory = new DepositHistory();            depositHistory.setSubmittedTime(sf.format(new Date()));            depositCardMapper.incrementMoney(depositCardId, money);            depositHistory.setFinishedTime(sf.format(new Date()));            depositHistory.setSerialNumber(UUID.randomUUID().toString().replace("-", ""));            depositHistory.setTransactionAmount(money);            depositHistory.setDepositCardId(depositCardId);            depositHistory.setStatus(1);            // 新增存款历史记录            depositHistoryMapper.save(depositHistory);            return ThriftDepositStatus.FINISHED;        } catch (Exception e) {            e.printStackTrace();            return ThriftDepositStatus.FAILED;        }    }    @Override    @Transactional    public ThriftWithdrawStatus withdrawMoney(String depositCardId, double money) throws TException {        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        try {            WithdrawHistory withdrawHistory = new WithdrawHistory();            withdrawHistory.setSubmittedTime(sf.format(new Date()));            depositCardMapper.decrementMoney(depositCardId, money);            withdrawHistory.setFinishedTime(sf.format(new Date()));            withdrawHistory.setSerialNumber(UUID.randomUUID().toString().replace("-", ""));            withdrawHistory.setTransactionAmount(money);            withdrawHistory.setDepositCardId(depositCardId);            withdrawHistory.setStatus(1);            // 新增取款历史记录            withdrawHistoryMapper.save(withdrawHistory);            return ThriftWithdrawStatus.FINISHED;        } catch (Exception e) {            e.printStackTrace();            return ThriftWithdrawStatus.FAILED;        }    }    @Override    public List<ThriftDeposit> queryDepositHistorys(String depositCardId) throws TException {        List<DepositHistory> depositHistory = depositHistoryMapper.queryDepositHistoryList(depositCardId);        // 查询存款历史纪录        return depositHistory.stream().map(DepositHistory::toThrift).collect(Collectors.toList());    }    @Override    public List<ThriftWithdraw> queryWithdrawHistorys(String depositCardId) throws TException {        List<WithdrawHistory> withdrawHistory = withdrawHistoryMapper.queryWithdrawHistoryList(depositCardId);        // 查询取款历史纪录        return withdrawHistory.stream().map(WithdrawHistory::toThrift).collect(Collectors.toList());    }}

Mybatis持久层,还是以 DepositCardMapper为例:

DepositCardMapper.java

@Repository@Mapperpublic interface DepositCardMapper {    int save(DepositCard record);    List<DepositCard> queryAllDepositCards(@Param("customerId") String customerId);    void decrementMoney(@Param("depositCardId") String depositCardId, @Param("money") Double money);    void incrementMoney(@Param("depositCardId") String depositCardId, @Param("money") Double money);    Long countRowsByCustomerId(@Param("customerId") String customerId);}

DepositCardMapper.xml

<insert id="save" parameterType="com.icekredit.rpc.thrift.examples.http.entities.DepositCard">    INSERT INTO deposit_card (id, is_vip, opening_time,                              account_balance, account_flow, branch_id,                              customer_id)    VALUES (#{id,jdbcType=VARCHAR}, #{isVip,jdbcType=BIT}, #{openingTime,jdbcType=VARCHAR},            #{accountBalance,jdbcType=DOUBLE}, #{accountFlow,jdbcType=DOUBLE}, #{branchId,jdbcType=BIGINT},            #{customerId,jdbcType=VARCHAR})</insert><select id="queryAllDepositCards" resultMap="BaseResultMap" parameterType="java.lang.String">    SELECT    <include refid="Base_Column_List"/>    FROM deposit_card    WHERE customer_id = #{customerId}</select><select id="countRowsByCustomerId" resultType="java.lang.Long" parameterType="java.lang.String">    SELECT COUNT(id)    FROM deposit_card    WHERE customer_id = #{customerId}</select><update id="decrementMoney">    UPDATE deposit_card    <set>        <if test="money != null">            account_balance = account_balance - #{money},        </if>    </set>    WHERE id = #{depositCardId}</update><update id="incrementMoney">    UPDATE deposit_card    <set>        <if test="money != null">            account_balance = account_balance + #{money},        </if>    </set>    WHERE id = #{depositCardId}</update>
客户端(deposit-client)

同样,在客户端模块引入:

  • spring-cloud-starter-thrift-client: thrift客户端的 starter程序。

  • deposit-iface:中间契约模块,这里作为客户端桩( Stub)程序。

pom.xml

<parent>    <groupId>com.icekredit.rpc.thrift.examples</groupId>    <artifactId>deposit</artifactId>    <version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>deposit-client</artifactId><dependencies>    <!-- Thrift相关依赖 -->    <dependency>        <groupId>com.icekredit.rpc.thrift</groupId>        <artifactId>spring-cloud-starter-thrift-client</artifactId>        <version>1.0-SNAPSHOT</version>    </dependency>    <dependency>        <groupId>com.icekredit.rpc.thrift.examples</groupId>        <artifactId>deposit-iface</artifactId>        <version>1.0-SNAPSHOT</version>    </dependency>    <!-- SpringBoot依赖 -->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-actuator</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency>    <!-- Spring Cloud Consul服务注册与发现 -->    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-consul-discovery</artifactId>    </dependency>    <!-- Spring Cloud声明式Restful客户端 -->    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-feign</artifactId>    </dependency>    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-ribbon</artifactId>    </dependency>    <!-- Swagger依赖 -->    <dependency>        <groupId>io.springfox</groupId>        <artifactId>springfox-swagger2</artifactId>        <version>2.6.1</version>    </dependency>    <dependency>        <groupId>io.springfox</groupId>        <artifactId>springfox-swagger-ui</artifactId>        <version>2.6.1</version>    </dependency></dependencies><dependencyManagement>    <dependencies>        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-dependencies</artifactId>            <version>${spring-cloud.version}</version>            <type>pom</type>            <scope>import</scope>        </dependency>    </dependencies></dependencyManagement><build>    <plugins>        <plugin>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-maven-plugin</artifactId>        </plugin>    </plugins></build>

在 application.yml中配置 thrift的客户端的的运行参数和 Consul 的服务注册与发现的参数:

application.yml

server:  port: 8080endpoints:  actuator:    sensitive: false    enabled: truemanagement:  security:    enabled: falsespring:  cloud:    consul:      host: 192.168.91.128      port: 8500      discovery:        register: false        register-health-check: true        health-check-interval: 30s      retry:        max-attempts: 3        max-interval: 2000  thrift:    client:      package-to-scan: com.icekredit.rpc.thrift.examples.thrift.client      service-model: hsHa      pool:        retry-times: 3        pool-max-total-per-key: 200        pool-min-idle-per-key: 10        pool-max-idle-per-key: 40        pool-max-wait: 10000        connect-timeout: 5000

客户端程序启动入口类,设置 SwaggerAPI所在的包路径名称,同时允许自身作为注册程序注册到注册中心。

@SpringBootApplication@EnableFeignClients@EnableDiscoveryClient@EnableSwagger2public class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }    @Bean    public Docket createRestfulApi() {        return new Docket(DocumentationType.SWAGGER_2)                .apiInfo(apiInfo())                .select()                .apis(RequestHandlerSelectors.basePackage("com.icekredit.rpc.thrift.examples"))                .paths(PathSelectors.any())                .build();    }    private ApiInfo apiInfo() {        return new ApiInfoBuilder()                .title("Deposit Client")                .description("Deposit Client")                .version("1.0")                .build();    }}

在客户端使用 @ThriftClient注解标识服务端的 thrift服务代理接口,代理服务 ID为 deposit-server-rpc,代理的目标类是 ThriftDepositCardService。

DepositCardThriftClient.java

@ThriftClient(serviceId = "deposit-server-rpc", refer = ThriftDepositCardService.class)public interface DepositCardThriftClient extends ThriftClientAware<ThriftDepositCardService.Client> {}

BankThriftClient.java

@ThriftClient(serviceId = "deposit-server-rpc", refer = ThriftBankService.class)public interface BankThriftClient extends ThriftClientAware<ThriftBankService.Client> {}

在客户端控制器中通过 ThriftReferer注入需要使用的服务代理接口,通过 thriftClient.client()即可获取 Thrift客户端桩对象,然后实现远程服务的调用。

DepositCardRpcController.java

@RestController@RequestMapping("/rpc/deposit")public class DepositCardRpcController {    @ThriftReferer    private DepositCardThriftClient thriftClient;    @GetMapping("/queryAllDepositCards")    public List<DepositCard> queryAllDepositCards(@RequestParam("customerId") String customerId)            throws Exception {        return thriftClient.client().queryAllDepositCards(customerId)                .stream().map(DepositCard::fromThrift)                .collect(Collectors.toList());    }    @PostMapping("/addNewDepositCard")    public void addNewDepositCard(DepositCard depositCard) throws Exception {        thriftClient.client().addNewDepositCard(depositCard.getCustomerId(), depositCard.toThrift());    }    @GetMapping("/depositMoney")    public ThriftDepositStatus depositMoney(@RequestParam("depositCardId") String depositCardId,                                            @RequestParam("money") double money) throws Exception {        return thriftClient.client().depositMoney(depositCardId, money);    }    @GetMapping("/withdrawMoney")    public ThriftWithdrawStatus withdrawMoney(@RequestParam("depositCardId") String depositCardId,                                              @RequestParam("money") double money) throws Exception {        return thriftClient.client().withdrawMoney(depositCardId, money);    }    @GetMapping("/queryDepositHistory")    public List<DepositHistory> queryDepositHistory(@RequestParam("depositCardId") String depositCardId)            throws Exception {        return thriftClient.client().queryDepositHistorys(depositCardId)                .stream().map(DepositHistory::fromThrift)                .collect(Collectors.toList());    }    @GetMapping("/queryWithdrawHistory")    public List<WithdrawHistory> queryWithdrawHistory(@RequestParam("depositCardId") String depositCardId)            throws Exception {        return thriftClient.client().queryWithdrawHistorys(depositCardId)                .stream().map(WithdrawHistory::fromThrift)                .collect(Collectors.toList());    }}

BankRpcController.java

@RestController@RequestMapping("/rpc/bank")public class BankRpcController {    @ThriftReferer    private BankThriftClient thriftClient;    @PostMapping("/addNewBank")    public void addNewBank(Bank bank) throws Exception {        thriftClient.client().registerNewBank(bank.toThrift());    }    @GetMapping("/getBankById")    public Bank getBankById(@RequestParam("bankId") Long bankId) throws Exception {        return Bank.fromThrift(thriftClient.client().getBankById(bankId));    }    @GetMapping("/queryAllBranchesByRegion")    public Map<Region, List<Branch>> queryAllBranchesByRegion(@RequestParam("bankId") Long bankId) throws Exception {        Map<ThriftRegion, List<ThriftBranch>> thriftRegionListMap = thriftClient.client()                .queryAllBranchesByRegion(bankId);        Map<Region, List<Branch>> regionListMap = new HashMap<>();        for (Map.Entry<ThriftRegion, List<ThriftBranch>> entry : thriftRegionListMap.entrySet()) {            ThriftRegion thriftRegion = entry.getKey();            Region region = Region.findByValue(thriftRegion.getValue());            List<ThriftBranch> thriftBranches = entry.getValue();            List<Branch> branchList = thriftBranches.stream().map(Branch::fromThrift).collect(Collectors.toList());            regionListMap.put(region, branchList);        }        return regionListMap;    }}

因为服务代理客户端接口使用 @ThriftClient标识,通过(服务ID + 客户端桩 + 版本号)唯一标识, 即使同时注入多个服务代理客户端接口, @ThriftReferer也可忽略注解属性的配置。

总结

有一点是肯定的,那就是在已有技术框架(比如说: Spring + Mybatis/JPA)内,为了提高服务的性能和吞吐量,而引入诸如 Thrift的 RPC框架,编程难度和复杂度是会大大提高的。好比一把双刃剑,技术选型时还需要多方面权衡利弊。

欢迎关注技术公众号: 零壹技术栈

本帐号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。

  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net