上一篇简单的阐述了 spring-cloud-thrift-starter 这个插件的配置和使用,并引入了一个 calculator的项目。本文将基于一个银行存款、取款的业务场景,给出一套 thrift在生产环境的应用案例。
首先设计如下几张简单的数据库表:银行( bank)、分支( branch)、银行卡( deposit_card)、客户( customer)、存款历史纪录( deposit_history)、取款历史纪录( withdraw_history)。
正文项目结构如下,依然是由三个模块组成:
deposit
deposit-client
deposit-iface
- deposit-server
关于 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框架,编程难度和复杂度是会大大提高的。好比一把双刃剑,技术选型时还需要多方面权衡利弊。
欢迎关注技术公众号: 零壹技术栈
本帐号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。