如果我们要进行远程微服之间的调用该如何完成呢,本文以案例推动以养老系统中老人支付购买商品为例,一步步实现远程微服务的调用。
目标
微服务之间的调用方式
老人支付
common模块设计
统一返回
package com.wnhz.ssc.common.result;import lombok.Getter;@Getter
public enum RespCode {SUCCESS(2000,"success"),FAILED(5000,"success"),INFO(8000,"INFO");int code;String msg;RespCode(int code, String msg) {this.code = code;this.msg = msg;}
}
package com.wnhz.ssc.common.result;import lombok.Getter;
import java.util.Date;/*** 设计统一的返回对象* @param <T>*/
@Getter
public class HttpResp<T> {private int code;private String msg;private T result;private Date time;private HttpResp(){}public static <T> HttpResp<T> success(T result){HttpResp<T> httpResp = new HttpResp<>();httpResp.code=RespCode.SUCCESS.getCode();httpResp.msg = RespCode.SUCCESS.getMsg();httpResp.result = result;httpResp.time = new Date();return httpResp;}public static <T> HttpResp<T> failed(T result){HttpResp<T> httpResp = new HttpResp<>();httpResp.code=RespCode.FAILED.getCode();httpResp.msg = RespCode.FAILED.getMsg();httpResp.result = result;httpResp.time = new Date();return httpResp;}}
支付模块

拆分业务
实体类
package com.wnhz.ssc.domain.entity.po;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.math.BigDecimal;
import java.util.Date;/*** 交易的实体类*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tranx_tab")
public class Tranx {@TableId(value = "tranx_id")private Long id;@TableField("tranx_account")private Long account;@TableField("tranx_money")private BigDecimal money;@TableField("tranx_status")private String status;@TableField("tranx_create_time")private Date createTime;
}
package com.wnhz.ssc.domain.entity.po;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.math.BigDecimal;
import java.util.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("account_tab")
public class Account {@TableId(value = "account_id")private Long id;@TableField("account_num")private Long num;@TableField("account_password")private String password;@TableField("account_status")private String status;@TableField("account_balance")private BigDecimal balance;@TableField("account_create_time")private Date createTime;
}
配置
bootstrap.yml
spring:application:name: ssc-cloud-paycenter#nacos配置cloud:nacos:config:server-addr: 192.168.201.81:7777namespace: ssc-cloud-idfile-extension: yamlshared-configs:- data-id: db.yamlgroup: DEVrefresh: true- data-id: mbatisplus.yamlgroup: DEVrefresh: truediscovery:server-addr: ${spring.cloud.nacos.config.server-addr}namespace: ${spring.cloud.nacos.config.namespace}group: DEV
老人模块
支付业务
bootstrap.yml
spring:application:name: ssc-cloud-older#nacos配置cloud:nacos:config:server-addr: 192.168.201.81:7777namespace: ssc-cloud-idfile-extension: yamldiscovery:server-addr: ${spring.cloud.nacos.config.server-addr}namespace: ${spring.cloud.nacos.config.namespace}group: DEV
创建RestTemplate
@Configuration
public class SscConfig {@Autowiredprivate RestTemplateBuilder restTemplateBuilder;@Beanpublic RestTemplate restTemplate() {return restTemplateBuilder.build();}
}
controller调用
@RestController
@RequestMapping("/api/older")
public class OlderController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("/getBlance")public HttpResp getBalance(long phone){String url = "http://localhost:20001/api/paycenter/getByNum?num="+phone;ResponseEntity<HttpResp> entity = restTemplate.getForEntity(url,HttpResp.class);return entity.getBody();}
}
测试
GET http://localhost:20010/api/older/getBlance?phone=1233321
远程调用
RestTemplate
将微服务能够负载均衡调用
loadBalance
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
@LoadBalanced@Beanpublic RestTemplate restTemplate() {return restTemplateBuilder.build();}
feign(OpenFeign)
带参数: @RequestParam
@FeignClient(value = "ssc-cloud-paycenter")
public interface IPaycenterFeign {@GetMapping("/api/paycenter/getByNum")HttpResp<Account> getByNum(@RequestParam("num") long num);
}
<dependencies><dependency><groupId>com.wnhz.ssc.cloud.common</groupId><artifactId>ssc-cloud-common</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>com.wnhz.ssc.cloud.paycenter.api</groupId><artifactId>ssc-cloud-paycenter-api</artifactId><version>0.0.1-SNAPSHOT</version></dependency></dependencies>
大家有兴趣可以尝试完成以下业务
老人模块进行支付业务。
- 和支付模块进行连接,验证用户的用户名num、密码password 确认连接成功。在连接成功后.
- 在确认连接成功后,产生token,时间30分钟,30分钟后如果在进行支付查询等业务,需要重新连接。将token存储redis中。
- 连接后,进行查询,支付等业务,需要携带连接的token,进行远程操作。
- 如果token过期,篡改等行为,终止连接,并通知调用方。
- 支付过程需要使用异步方式完成(自定义线程池)。
- 页面
- 老人模块等待支付的响应,在30秒没有响应,继续等待1分钟,3分钟,如果3分钟之后任然没有获取结果则发起请求查询。
- 请将交易记录记。录到tranx_tab中。