Grain mall harvest record 1

Grain mall harvest record 1

The famous cereal mall in Silicon Valley, open source station B, recently read it and prepared to take notes.
Make more records and leave some traces.

About mybatis query, nested query

I have seen a lot of Raytheon's query methods, including tree structure and non tree structure query. The simple query is used. In mybatis, there is no connection query and the connection query is reduced. This situation will reduce the Cartesian product query in mysql query and slow down the efficiency.

Introduce jmeter tool for stress test

After writing the interface, you often don't know the efficiency and concurrency. You can use jmeter to test. The places that drag down the throughput are often network connections and IO operations, which are mainly caused by the following aspects:

  1. Insufficient jvm memory allocation
  2. Various remote calls are used in the project, including the use of business and middleware. The long link will also lead to long response time and low throughput
  3. Business code writing problems, such as a large number of queries to databases and inefficient sql, should reduce inefficient sql in the business and introduce caching to reduce database operations

nginx, reverse proxy, dynamic and static separation

  1. nginx reverse proxy protects the service of the server and can balance the load of the gateway layer;
  2. The static and dynamic separation method is adopted to put the static resources such as pictures, js and css in the business into the specified path of nginx, which can reduce the access of these resources to tomcat, shorten the access path of this kind and improve the throughput.
  3. We can forward the url of the main domain name and the sub domain name to the specific domain name in the NGX service.
www.gulimail.com   Primary domain name
search.gulimail.com Subdomain name

Retrieval service using ES

es can carry out multi condition retrieval, use inverted index, and find specific content according to words. There are a lot of things, so I don't write any more..

Introduce cache

In order to solve the throughput problem, we use the cache, which belongs to redis. We can set the displayed redisTemplate, or introduce spring cache to use redis (redis related configurations and packages are introduced by ourselves). The following steps are as follows:

  1. Introduce dependency
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

2. redis is configured in the configuration file as the cache

spring.cache.type=redis

3. Configuration annotation

@EnableCaching   Open annotation

@Cacheable Query database cache
@CacheEvict Add, delete and modify methods, delete cache (failure mode)
@CachePut Add, delete and modify methods: after modifying the database, write to the cache (double write mode)
@Caching Combine the above notes

Distributed lock

Some businesses cannot avoid using locks, but they involve distributed project deployment, so distributed locks are used to solve them. redis is considered as a distributed lock.

redis meets the conditions of distributed lock:

  1. Every operation of redis is an atomic operation;
  2. The lock should be unlocked automatically. Because it may be down, redis can set the expiration time
  3. Lock reentry may be called many times. When redis sets the key, the current thread id can be put in, or timing can be added
  4. For lock renewal, the processing request may not be completed during the scheduled period, the timing may be introduced, or the time may be a little longer

Redistribute distributed lock introduction

//springboot integration package
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.16.4</version>
</dependency>

Use the Lock method in java JUC package

Asynchronous choreography task

Sometimes, when performing operations, concurrent operations can improve our efficiency and reduce the response time. For example, in a scenario, first query data table 1, then query data table 2, and finally integrate the results of 1 and 2, and then return them to the interface. During this period, the operations of query 1 and query 2 are not related. We can operate asynchronously. When assembling the results, we need to wait for the results of 1 and 2.

CompletableFuture

Completable Future combines the advantages of Future and provides a very powerful extension function of Future. It can help us simplify the complexity of asynchronous programming, provide the ability of functional programming, process the calculation results through callback, and provide the method of converting and combining completable Future. It's really fragrant!

//There is no backvalue task and it is executed using the provided thread pool
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor);
//There is a reverse value task, which is executed using the provided thread pool
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor);
f1.thenRun(Runnable b)  //The result of f1 cannot be passed into b, and the whole method has no return value
f1.thenAccept(FunctionalInterface b) //The value b of f1 can be used, but the whole method has no return value
f1.thenApply(FunctionalInterface b) //The value b of f1 can be used, and the whole method has a return value
f1.thenRun(Runnable b)  //The result of f1 cannot be passed into b, and the whole method has no return value
f1.thenAccept(FunctionalInterface b) //The value b of f1 can be used, but the whole method has no return value
f1.thenApply(FunctionalInterface b) //The value b of f1 can be used, and the whole method has a return value

Check the use of this method in detail!

Add necessary parameters to Feign call

Feign encapsulates httpclient in the bottom layer and calls it through proxy mode. Note that when calling remote interfaces, some interfaces need requests with special parameters or special header s, which should be set automatically.

1. Call feign on the same thread

Set the RequestInterceptor. This interceptor will be used for packaging before feign calls. In the feign configuration class, bean annotations can be used to inject an interceptor, which sets the request information of the original context

@Bean
public RequestInterceptor requestInterceptor() {
	return new RequestInterceptor() {
		@Override
        public void apply(RequestTemplate template) {
           //spring provides request parameters from the current thread context
	 ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
	 	//Set into template 
	 	template.header("token",token);	
        }
	} 	
}

2. feign is called by a different thread

The above method cannot obtain the header information of the first request because there are two threads
Therefore, on the basis of the above, we have to add another step, that is, to synchronize the thread header information with request parameters to asynchronous threads

// Gets the current thread context manager
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//Asynchronous thread
CompletableFuture<Void> addressFuture = CompletableFuture.runAsync(() -> {
     // The synchronous context environment resolves that asynchrony cannot obtain RequestAttributes from ThreadLocal
     RequestContextHolder.setRequestAttributes(requestAttributes);
    //Call feign
 	memberFeignservice.getAddress();     
        }, executor);

Tags: Spring Cloud

Posted by youngp on Thu, 14 Apr 2022 15:38:51 +0930