How interfaces idempotency implementation of the interface idempotency achieve?

How interfaces Idempotence achieve?

 

REVIEW

  • Reprinted from how idempotency achieve? In-depth understanding of a wave! ! !
  • Now this time we may be most concerned about is money, then you have not thought about bank transfer you do not have to turn more than once, or fail, or succeed, why not turn more than a sum of mistakes about it? Wake up, young man, do not dream, the bank can do stupid x it?
  • Today we'll talk about why the bank transfer can not give me a sum of turn? Relates to the question of money, little friends cheer! ! !
  • To want to understand these doubts, we must mention a concept is idempotency, as to what is idempotency, how idempotency through the code, the following will describe in detail.

What is Idempotence

  • The so-called idempotent is a popular request and repeated requests to produce the same side effects with a resource. Mathematical language is f(x)=f(f(x)).
  • Wikipedia idempotency defined as follows:
幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。
在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“setTrue()”函数就是一个幂等函数,无论多次执行,其结果都是一样的,更复杂的操作幂等保证是利用唯一交易号(流水号)实现.

Why do we need Idempotence

  • In highly concurrent system environment, most likely because of the network, blocking and so on lead to the client or the caller does not receive timely feedback server even call a timeout issue. In short, the requesting party is calling your service, but did not receive any information, completely ignorant to force the state. For example, the issue of the order, you may encounter several problems as follows:
  1. When you create an order, the first call to service timeout, called again whether a two pen orders?
  2. When an order is successfully created to reduce inventory, reduce inventory first time out, will buckle more than once?
  3. When the order to pay, the server deducting money successfully, but the interface feedback timeout, this time calling to pay again, will subtract sum it?
  • As a consumer, you can accept the first two, the third case on MMP, ha ha ha! ! ! This situation generally has the following two solutions
  1. Services provided by a query operation is successful api, for the first time after a timeout, the caller calls the query interface, if left found the success of the process, failed and left the failed process.
  2. Another is the service side need to use power and other means to ensure a consistent and repeated requests result.

HTTP idempotency

  • GET: just access to resources, without any side effects on its own resources, natural idempotent.
  • HEAD: GET essentially the same, acquiring header information, mainly living explore the role of idempotent.
  • OPTIONS: URL acquisition method supported by the current, and therefore idempotent of.
  • DELETE: to delete the resource, have side effects, but it should meet idempotency, such as deleting a resource based on the id, the caller can call N times without worrying about errors caused (according to business needs change).
  • PUT: used to update the resource, it has side effects, but it should meet idempotency, such as id based on updated data, called many times and the role of N times are the same (based on business needs change).
  • POST: for adding resources, multiple submissions are likely to produce side effects, such as order submission, multiple submissions are likely to have multiple orders.

Implementation of idempotency

  • For client interaction interface, can intercept the front end part, for example, prevent duplicate form submission button is grayed out, hidden, not click like. But the front-end interceptor is clearly aimed at the average user, understand the point of technology can simulate request call interface, so the back-end idempotency very important.
  • How idempotency back-end implementation? We will introduce the following aspects.

De-duplication database table

  • When inserting data into the database, the database using a unique index characteristics to ensure that only data. For example, the order of the serial number, or a combination of multiple fields.
  • Is relatively simple, readers can achieve their own look, this is no longer provided a demo.

state machine

  • Many businesses have more and more states, such as the status of orders have to submit, to be paid, paid, canceled, refunds state. Backend can go to ensure idempotency Depending on the state, such as when the refund, we must ensure that the status of this order is already paid.
  • Business often appeared, readers can achieve their own look, no longer offer demo.

TOKEN mechanism

  • Click for a client or continuous retry timeout caller, etc., such as submitting orders, such an operation can be achieved with a Token mechanism to prevent duplicate submission.
  • How TOKEN mechanism to achieve? Simply means that the caller when the call interface Xianxiang a global ID request to the rear end (the TOKEN), when the global ID request carrying the request together with the rear end of the need to ensure the global ID verification idempotent operation process is as follows Figure:

  • The main process steps:
    • The client first sends a token acquisition request, the server generates a globally unique ID is stored in redis while the ID is returned to the client.
    • The client calls when the service request must carry this token, usually on the request head.
    • The server will check this Token, if the check is successful, the execution of business.
    • If the check fails, then repeat the operation, return the results directly to the client specified.
  • Through the above process analysis, the only focus is on how the global unique ID generation, often there will be a global ID generation services in a distributed service to ensure the uniqueness of ID, but the quantities and more difficult to achieve, UUID data some relatively large, here is the reader of choice Chen snow algorithm to generate globally unique ID, do not understand the algorithm snowflakes article will highlight.

Code

  • Chen environment of choice is a stand-alone environment SpringBoot + Redis + Notes + interceptor ways, just show you ideas, specific code can reference implementation.
  • How redis implemented, gets Token interface globally unique Id stored Redis (be sure to set the expiration time, according to business needs), when the service request is deleted from redis, depending delete the return value judgment, returns true if the first request returns false represents repeat request. code show as below:
@Service
public class TokenServiceImpl implements TokenService { @Autowired private StringRedisTemplate stringRedisTemplate; @Override public String getToken() { //获取全局唯一id long nextId = SnowflakeUtil.nextId(); //存入redis,设置10分钟失效 stringRedisTemplate.opsForValue().set(String.valueOf(nextId), UUID.randomUUID().toString(),10, TimeUnit.MINUTES); return String.valueOf(nextId); } /** * 删除记录,true表示第一次提交,false重复提交 */ @Override public Boolean checkToken(String token) { return stringRedisTemplate.delete(token); } } 
  • Implementation Notes below, marked on the controller based on the current class represents all interfaces do idempotent denoted by a single method, do denotes a single interface idempotent operations.
/**
 * @Description 幂等操作的注解
 * @Author CJB
 * @Date 2020/3/25 10:19
 */
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RepeatLimiter { } 
  • Request interceptor header, for extracting header and request verification request header, as follows:
/**
 * @Description 获取请求头的信息,具体校验逻辑读者自己实现
 * @Author CJB
 * @Date 2020/3/25 11:09
 */
@Component public class HeaderIntercept implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //获取token String token = request.getHeader(HeaderConstant.TOKEN); //校验逻辑 if (!validToken(token)) throw new TokenInvalidException("TOKEN失效"); //获取其他的参数..... RequestHeader header = RequestHeader.builder() .token(token) .build(); //放入request中 request.setAttribute(HeaderConstant.HEADER_INFO,header); return true; } /** * 校验token,逻辑自己实现 * @param token * @return */ private boolean validToken(String token){ return Boolean.TRUE; } } 
  • Ensure idempotency interceptors, delete token directly from redis, the success of the first submission, resubmit unsuccessful.
@Component
public class RepeatIntercept implements HandlerInterceptor { @Autowired private TokenService tokenService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod){ //获取方法上的参数 RepeatLimiter repeatLimiter = AnnotationUtils.findAnnotation(((HandlerMethod) handler).getMethod(), RepeatLimiter.class); if (Objects.isNull(repeatLimiter)){ //获取controller类上注解 repeatLimiter=AnnotationUtils.findAnnotation(((HandlerMethod) handler).getBean().getClass(),RepeatLimiter.class); } //使用注解,需要拦截验证 if (Objects.nonNull(repeatLimiter)){ //获取全局token,表单提交的唯一id RequestHeader info = RequestContextUtils.getHeaderInfo(); //没有携带token,抛异常,这里的异常需要全局捕获 if (StringUtils.isEmpty(info.getToken())) throw new RepeatException(); //校验token Boolean flag = tokenService.checkToken(info.getToken()); //删除失败,表示 if (Boolean.FALSE.equals(flag)) //抛出重复提交的异常 throw new RepeatException(); } } return true; } } 
  • Interface idempotent achieved, as follows:
@RestController
@RequestMapping("/order")
public class OrderController { @Autowired private OrderService orderService; /** * 下单 * @param order * @return */ @PostMapping @RepeatLimiter //幂等性保证 public CommenResult add(@RequestBody Order order){ orderService.save(order); return new CommenResult("200","下单成功"); } } 

Show

  • Token acquisition request sent getToken

  • Token carrying orders for the first time:

  • Second order:

 

REVIEW

  • Reprinted from how idempotency achieve? In-depth understanding of a wave! ! !
  • Now this time we may be most concerned about is money, then you have not thought about bank transfer you do not have to turn more than once, or fail, or succeed, why not turn more than a sum of mistakes about it? Wake up, young man, do not dream, the bank can do stupid x it?
  • Today we'll talk about why the bank transfer can not give me a sum of turn? Relates to the question of money, little friends cheer! ! !
  • To want to understand these doubts, we must mention a concept is idempotency, as to what is idempotency, how idempotency through the code, the following will describe in detail.

What is Idempotence

  • The so-called idempotent is a popular request and repeated requests to produce the same side effects with a resource. Mathematical language is f(x)=f(f(x)).
  • Wikipedia idempotency defined as follows:
幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。
在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“setTrue()”函数就是一个幂等函数,无论多次执行,其结果都是一样的,更复杂的操作幂等保证是利用唯一交易号(流水号)实现.

Why do we need Idempotence

  • In highly concurrent system environment, most likely because of the network, blocking and so on lead to the client or the caller does not receive timely feedback server even call a timeout issue. In short, the requesting party is calling your service, but did not receive any information, completely ignorant to force the state. For example, the issue of the order, you may encounter several problems as follows:
  1. When you create an order, the first call to service timeout, called again whether a two pen orders?
  2. When an order is successfully created to reduce inventory, reduce inventory first time out, will buckle more than once?
  3. When the order to pay, the server deducting money successfully, but the interface feedback timeout, this time calling to pay again, will subtract sum it?
  • As a consumer, you can accept the first two, the third case on MMP, ha ha ha! ! ! This situation generally has the following two solutions
  1. Services provided by a query operation is successful api, for the first time after a timeout, the caller calls the query interface, if left found the success of the process, failed and left the failed process.
  2. Another is the service side need to use power and other means to ensure a consistent and repeated requests result.

HTTP idempotency

  • GET: just access to resources, without any side effects on its own resources, natural idempotent.
  • HEAD: GET essentially the same, acquiring header information, mainly living explore the role of idempotent.
  • OPTIONS: URL acquisition method supported by the current, and therefore idempotent of.
  • DELETE: to delete the resource, have side effects, but it should meet idempotency, such as deleting a resource based on the id, the caller can call N times without worrying about errors caused (according to business needs change).
  • PUT: used to update the resource, it has side effects, but it should meet idempotency, such as id based on updated data, called many times and the role of N times are the same (based on business needs change).
  • POST: for adding resources, multiple submissions are likely to produce side effects, such as order submission, multiple submissions are likely to have multiple orders.

Implementation of idempotency

  • For client interaction interface, can intercept the front end part, for example, prevent duplicate form submission button is grayed out, hidden, not click like. But the front-end interceptor is clearly aimed at the average user, understand the point of technology can simulate request call interface, so the back-end idempotency very important.
  • How idempotency back-end implementation? We will introduce the following aspects.

De-duplication database table

  • When inserting data into the database, the database using a unique index characteristics to ensure that only data. For example, the order of the serial number, or a combination of multiple fields.
  • Is relatively simple, readers can achieve their own look, this is no longer provided a demo.

state machine

  • Many businesses have more and more states, such as the status of orders have to submit, to be paid, paid, canceled, refunds state. Backend can go to ensure idempotency Depending on the state, such as when the refund, we must ensure that the status of this order is already paid.
  • Business often appeared, readers can achieve their own look, no longer offer demo.

TOKEN mechanism

  • Click for a client or continuous retry timeout caller, etc., such as submitting orders, such an operation can be achieved with a Token mechanism to prevent duplicate submission.
  • How TOKEN mechanism to achieve? Simply means that the caller when the call interface Xianxiang a global ID request to the rear end (the TOKEN), when the global ID request carrying the request together with the rear end of the need to ensure the global ID verification idempotent operation process is as follows Figure:

  • The main process steps:
    • The client first sends a token acquisition request, the server generates a globally unique ID is stored in redis while the ID is returned to the client.
    • The client calls when the service request must carry this token, usually on the request head.
    • The server will check this Token, if the check is successful, the execution of business.
    • If the check fails, then repeat the operation, return the results directly to the client specified.
  • Through the above process analysis, the only focus is on how the global unique ID generation, often there will be a global ID generation services in a distributed service to ensure the uniqueness of ID, but the quantities and more difficult to achieve, UUID data some relatively large, here is the reader of choice Chen snow algorithm to generate globally unique ID, do not understand the algorithm snowflakes article will highlight.

Code

  • Chen environment of choice is a stand-alone environment SpringBoot + Redis + Notes + interceptor ways, just show you ideas, specific code can reference implementation.
  • How redis implemented, gets Token interface globally unique Id stored Redis (be sure to set the expiration time, according to business needs), when the service request is deleted from redis, depending delete the return value judgment, returns true if the first request returns false represents repeat request. code show as below:
@Service
public class TokenServiceImpl implements TokenService { @Autowired private StringRedisTemplate stringRedisTemplate; @Override public String getToken() { //获取全局唯一id long nextId = SnowflakeUtil.nextId(); //存入redis,设置10分钟失效 stringRedisTemplate.opsForValue().set(String.valueOf(nextId), UUID.randomUUID().toString(),10, TimeUnit.MINUTES); return String.valueOf(nextId); } /** * 删除记录,true表示第一次提交,false重复提交 */ @Override public Boolean checkToken(String token) { return stringRedisTemplate.delete(token); } } 
  • Implementation Notes below, marked on the controller based on the current class represents all interfaces do idempotent denoted by a single method, do denotes a single interface idempotent operations.
/**
 * @Description 幂等操作的注解
 * @Author CJB
 * @Date 2020/3/25 10:19
 */
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RepeatLimiter { } 
  • Request interceptor header, for extracting header and request verification request header, as follows:
/**
 * @Description 获取请求头的信息,具体校验逻辑读者自己实现
 * @Author CJB
 * @Date 2020/3/25 11:09
 */
@Component public class HeaderIntercept implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //获取token String token = request.getHeader(HeaderConstant.TOKEN); //校验逻辑 if (!validToken(token)) throw new TokenInvalidException("TOKEN失效"); //获取其他的参数..... RequestHeader header = RequestHeader.builder() .token(token) .build(); //放入request中 request.setAttribute(HeaderConstant.HEADER_INFO,header); return true; } /** * 校验token,逻辑自己实现 * @param token * @return */ private boolean validToken(String token){ return Boolean.TRUE; } } 
  • Ensure idempotency interceptors, delete token directly from redis, the success of the first submission, resubmit unsuccessful.
@Component
public class RepeatIntercept implements HandlerInterceptor { @Autowired private TokenService tokenService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod){ //获取方法上的参数 RepeatLimiter repeatLimiter = AnnotationUtils.findAnnotation(((HandlerMethod) handler).getMethod(), RepeatLimiter.class); if (Objects.isNull(repeatLimiter)){ //获取controller类上注解 repeatLimiter=AnnotationUtils.findAnnotation(((HandlerMethod) handler).getBean().getClass(),RepeatLimiter.class); } //使用注解,需要拦截验证 if (Objects.nonNull(repeatLimiter)){ //获取全局token,表单提交的唯一id RequestHeader info = RequestContextUtils.getHeaderInfo(); //没有携带token,抛异常,这里的异常需要全局捕获 if (StringUtils.isEmpty(info.getToken())) throw new RepeatException(); //校验token Boolean flag = tokenService.checkToken(info.getToken()); //删除失败,表示 if (Boolean.FALSE.equals(flag)) //抛出重复提交的异常 throw new RepeatException(); } } return true; } } 
  • Interface idempotent achieved, as follows:
@RestController
@RequestMapping("/order")
public class OrderController { @Autowired private OrderService orderService; /** * 下单 * @param order * @return */ @PostMapping @RepeatLimiter //幂等性保证 public CommenResult add(@RequestBody Order order){ orderService.save(order); return new CommenResult("200","下单成功"); } } 

Show

  • Token acquisition request sent getToken

  • Token carrying orders for the first time:

  • Second order:

 

Guess you like

Origin www.cnblogs.com/Leo_wl/p/12640651.html