前言
上一篇简单的阐述了 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: falseenabled: truemanagement:security:enabled: falsespring:datasource:druid:url: jdbc:mysql://localhost:3306/deposit?useUnicode=true&characterEncoding=utf-8driver-class-name: com.mysql.jdbc.Driverusername: rootpassword: rootthrift:server:service-id: deposit-server-rpcservice-model: hsHaport: 25000worker-queue-capacity: 1000hs-ha:min-worker-threads: 5max-worker-threads: 20keep-alived-time: 3mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.icekredit.rpc.thrift.examples.http.entitieslogging:level:root: INFOcom:icekredit:rpc:thrift:examples:mapper: DEBUG
服务端程序启动入口类,设置 SwaggerAPI所在的包路径名称。
Application.java
@SpringBootApplication@EnableSwagger2public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}@Beanpublic 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;@Autowiredpublic 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;}@Overridepublic 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.findB8000yId(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@Transactionalpublic void addNewDepositCard(String customerId, ThriftDepositCard depositCard) throws TException {DepositCard newDepositCard = DepositCard.fromThrift(depositCard);// 新增银行卡信息depositCardMapper.save(newDepositCard);}@Override@Transactionalpublic 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@Transactionalpublic 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;}}@Overridepublic List<ThriftDeposit> queryDepositHistorys(String depositCardId) throws TException {List<DepositHistory> depositHistory = depositHistoryMapper.queryDepositHistoryList(depositCardId);// 查询存款历史纪录return depositHistory.stream().map(DepositHistory::toThrift).collect(Collectors.toList());}@Overridepublic 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_cardWHERE customer_id = #{customerId}</select><select id=\"countRowsByCustomerId\" resultType=\"java.lang.Long\" parameterType=\"java.lang.String\">SELECT COUNT(id)FROM deposit_cardWHERE 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: falseenabled: truemanagement:security:enabled: falsespring:cloud:consul:host: 192.168.91.128port: 8500discovery:register: falseregister-health-check: truehealth-check-interval: 30sretry:max-attempts: 3max-interval: 2000thrift:client:package-to-scan: com.icekredit.rpc.thrift.examples.thrift.clientservice-model: hsHapool:retry-times: 3pool-max-total-per-key: 200pool-min-idle-per-key: 10pool-max-idle-per-key: 40pool-max-wait: 10000connect-timeout: 5000
客户端程序启动入口类,设置 SwaggerAPI所在的包路径名称,同时允许自身作为注册程序注册到注册中心。
@SpringBootApplication@EnableFeignClients@EnableDiscoveryClient@EnableSwagger2public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}@Beanpublic 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 {@ThriftRefererprivate 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 {@ThriftRefererprivate 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框架,编程难度和复杂度是会大大提高的。好比一把双刃剑,技术选型时还需要多方面权衡利弊。
欢迎关注技术公众号: 零壹技术栈
本帐号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。