laitimes

How to write caching code elegantly

author:Flash Gene

In daily coding practice, caching is often used to solve the problem of high concurrency, and caching can be said to be the only tool to solve the traffic peak. Although the group middleware team has built the caching infrastructure and helped us solve most of the problems, there are still the following types of problems when the application side calls the caching API in the actual coding process:

  1. The logic of using the cache is very general, basically check the cache first, return it directly, and then put it into the cache without checking the DB. This general logic is scattered throughout the system, violating the principle of high cohesion and low coupling.
  2. The cache code and the business logic code are deeply coupled, which not only reduces the readability of the code, but also adds additional system complexity.
  3. If you want to switch cache (MDB->LDB) or API upgrade, all the code involved needs to be changed.
  4. If you want to solve similar general problems such as cache breakdown, cache penetration, and cascading cache, you need to solve them through the framework.

Therefore, what is a cache and how to choose a certain kind of cache is not the focus of this article, today I will write how to separate the cache code from the business code in the actual coding process, so as to make the code more concise and easier to read.

How to write caching code elegantly

Practical analysis

Read the cache data first, return it directly if there is data, read the DB data if it is not read, and update the cache after the data is returned.

How to write caching code elegantly

This kind of scenario, in daily coding, is very common and too simple, but the actual code is indeed very different, listed as follows:

▐Traditional writing

Whatever cache is used, it is directly used and embedded in the business code. This kind of code is not to be seen when it is code review, or when future generations learn business code, the reason is very simple, it has nothing to do with the actual business function, I don't want to know what cache you use, how you encode the cache code.

How to write caching code elegantly
How to write caching code elegantly

▐ A more advanced way to write

Compared with the traditional way of writing, in order to solve the problem of caching various data formats (List, Map, etc.) and various object serialization (java, json), the team can encapsulate the cache into a simple API for everyone's convenience. It's easy to use, but the code is still embedded in the business code and not stripped out.

How to write caching code elegantly
How to write caching code elegantly

▐ Annotation writing

Finally, the annotation method, compared with the first two ways of writing, the code has been stripped from the business code, and people who read the code will only care about how the business function is implemented, which cache to use, and how to implement it, which can be completely ignored.

How to write caching code elegantly
How to write caching code elegantly

spring cache方案分析

Spring Cache uses dynamic proxies to process cache-related operations in the proxy class, and at the same time calls the methods in the proxied class, so that the operation cached code and business code can be separated, and when the cache capability needs to be strengthened in the later stage, only the methods in the proxy class need to be modified.

How to write caching code elegantly

That's how Spring Cache works. Spring Cache is a general-purpose caching framework provided by Spring. It uses AOP to implement annotation-based caching, so that developers don't need to care about what caching framework is used at the bottom, and only need to simply add an annotation to the method to implement the caching function. With Spring Cache, users can quickly develop a very good caching function.

▐Code directory

How to write caching code elegantly

▐Annotated maps

How to write caching code elegantly

▐Examples of annotation usage

@Cacheable(value = "user_cache", unless = "#result == null")
public User getUserById(Long id) {
 return userMapper.getUserById(id);
}
@CachePut(value = "user_cache", key = "#user.id", unless = "#result == null")
public User updateUser(User user) {
 userMapper.updateUser(user);
 return user;
}
@CacheEvict(value = "user_cache", key = "#id")
public void deleteUserById(Long id) {
 userMapper.deleteUserById(id);
}           

▐Scenario analysis

Spring Cache is powerful and elegantly designed. It is especially suitable for scenarios where the cache control is not so detailed, such as static display pages, likes, rankings, etc., which are characterized by the fact that there are no strict requirements for the real-time nature of the data, and only the data source needs to be cached and automatically refreshed after expiration. In these scenarios, Spring Cache is an artifact that can greatly improve R&D efficiency.

However, in scenarios with high concurrent large data volumes, it is still necessary to expand the function in the control of fine cache granularity.

  1. multi-level caching;
  2. The cache is refreshed periodically;
  3. list caching;
  4. Cache CPP protection mechanism;
  5. Cache count.

For example, Spring Cache does not have a second-level caching implementation

How to write caching code elegantly
How to write caching code elegantly

Customize the cache scheme

Learn the Spring Cache framework scheme and implement a custom Cache framework, which not only retains the advantages of the Spring Cache framework, but also implements many missing capabilities of Spring Cache, such as cache breakdown, cache penetration protection, and multi-level caching.

▐Annotation code examples

How to write caching code elegantly
How to write caching code elegantly

▐Solution architecture

How to write caching code elegantly
How to write caching code elegantly

Write at the end

With the help of the Spring Cache implementation, a custom caching framework is built, and many annotations are extended, such as counting, cache refresh, list caching, distributed locks, multi-level caching, etc., which not only realizes the separation of cache code and business code, but also expands the capabilities of Spring caching, greatly improves the readability of code, and reduces the efficiency of cache code maintenance.

Author: Qiao Fan

Source-WeChat public account: big Taobao technology

Source: https://mp.weixin.qq.com/s/ZHMKPBtMfTD8vCAPdc99YQ