A premise

I haven’t updated my article for more than a month. I was delayed for one or two weeks because of the Chinese New Year in early February. Then at the end of February, something happened and I was not in a good mood. I have nothing to do recently. I found the project I was working on when I just graduated from a network disk that I had not used for a long time. I was deeply touched, so I wanted to write an article to summarize what I had done in the past four years.

Two before the introduction of the broken read

I don’t know if you have ever felt that as you work longer hours, you can always look back and get some different insights. The logic at the bottom, which I had been unable to understand and thought was obscure, suddenly felt clear and clear when I looked at it now. I could even have association immediately and put some scenes on it to hang on my knowledge tree.

For example, when I first graduated, I only knew the written principles of Synchronized and volatile by heart, but I had no idea where they were really used. It was only later when I looked at some of the concurrent synchronization components that I found them hanging around here. Those synchronous components have more than that underneath them. In the case of the synchronizer, there are FIFO queue data structures, production-consumption design patterns waiting to wake up, and template patterns that encapsulate component code to provide API usage. It’s like a playbook, where all the clues come together, and everything falls into place.

Moving from one company to another, working on different projects, I calmly reviewed the code of my past projects.

Graduation work projects

When I first started working, I joined an online education startup company. At the beginning of work, the master has not let himself do the project, only to tell himself, now the whole company background system wants to do a unified login authentication service, you go to study and research, see how to do it. I am a little confused, before only understand the single service, what is the unified login service, micro service? Hurry up and make up for it. After that, while learning micro-service knowledge, I asked for the meaning of the master. After stumbling all the way, I gradually understood what the service to do should do and what the structure should look like.

 

Central Taiwan – Login verification service

Project Background:

Each project background management system, which operation permissions need to be corresponding to each group, some pages are not operable for all. The business level is divided into three modules: user, group and background interface API. Where, THE API should be divided into groups, indicating that the user has certain permissions, and which groups should the user belong to if he wants to have permissions.

   

The overall architecture is shown in the figure below:

A SpringCloud microservice

The overall service is based on Springcloud microservices, and all services and Zuul interactions need to be registered with Eureka.

Deploy a separate Auth-Center service system

1 is mainly responsible for providing user information permission, user group, url permission allocation of add, delete, check and change interface call

public class User implements Serializable {
    private int id;
    private String userName;
    private String password;
    private int status;
    private int role;
    private String email;
    private String phone;
    private Date createTime;
    private Date modifyTime;
}


public class Group implements Serializable {
    private int id;
    private String groupName;
    private int status;
    private String server;
    private String url;
}


public class UserGroupRelation implements Serializable {
    private int userId;
    private int groupId;
   }
Copy the code

2. A separate RPC interface is used for authorization verification of Zuul service, and Feign is used for RPC remote call

@FeignClient("auth-center")
@RequestMapping("/authCenter")
public interface CheckTokenService {
 
    @RequestMapping(value = "/verifyToken", method = RequestMethod.POST)
    AuthenUser test(@RequestParam("token") String token,
                    @RequestParam("url") String url,
                    @RequestParam("server") String server);
Copy the code

 

3. Develop a unified servlet JAR package to obtain all urls under RequestMapping annotations for permission allocation based on reflection principle. Each service can simply inject the servlet into the Spring IOC container.

RequestMappingHandlerMapping rmhp = springContextHelper.getObject(RequestMappingHandlerMapping.class); try { Map<RequestMappingInfo, HandlerMethod> map = rmhp.getHandlerMethods(); for (RequestMappingInfo info : map.keySet()) { HandlerMethod hm = map.get(info); Class<? > scannerClass = hm.getBeanType(); ClassScanInfo classScanInfo = scannerHelper.getAllMappingUrl(scannerClass); projectUrls.add(classScanInfo); } print(resp, new Protocol(ResponseCode.OK, projectUrls)); } catch (Exception e) { e.printStackTrace(); }Copy the code

Three zuul service

The core Filter component in Zuul overwrites the Filter of type Pre and calls the Auth-Center interface to determine whether the URL forwards or rejects the request.

AuthenUser authenUser = verifyTokenService.test(token, uri, server);
Copy the code

Main business items of the company

Then I got on the right track and began to take over projects in the company. Most of the projects in the company are in the form of purchasing members, reciting English words, punching cards and repaying tuition fees.

Business scenarios include user purchase of courses, order generation, class experience, entertainment interaction, clocking tuition refund, distribution and so on. Here is a brief memory of a few memorable business scenarios at that time.

Read the leaderboard every time you open your mouth

The target of the project is K12, who are all young friends. The product wants to design a list of open English reading, so as to make the product more interesting and attract children to open English reading.

The bottom layer is implemented with the Zset object of Redis, score is the opening times, value is childId, and when adding one, the incR method of Redis is used to realize self-increment. Because the product only needs to show the first 500 users, use a math.random () function where the probability is less than or equal to 10 percent. At intervals, useless data is cleaned up to ensure that the query does not time out.

If (temp < = 0.1) {RedisClient. Expire (weekSpeakRankRedisTemplate weekCache, 42 l, TimeUnit. DAYS); RedisClient.zremoveRange(weekSpeakRankRedisTemplate, weekCache, 0, -501); }Copy the code

Two conversion code

Redis’s Set object stores the exchange code, which is simply generated using UUID and de-duplicated at the bottom of the collection object. Every time the user calls the interface to obtain the exchange code, the elements are removed from the Set SPOP and inserted into the database to store the user and exchange code usage status.

String code = UUID.randomUUID().toString().substring(0, 18).replaceAll("-", "").replaceAll("0", "o").toUpperCase();
Copy the code

 

Three regular job

I still remember that I used the cron command to schedule a controller on the server to implement regular task execution. Sometimes, in order to avoid concurrent execution of scheduled tasks, businesses also need to add redis distributed lock developed by the company in the front of the code. Since then, the company has combined Spring scheduled + time wheel custom framework to achieve task scheduling, and now I use XXL_Job to achieve scheduled tasks. Ha ha, can’t help feeling a lot.

 

4 Service degradation

Some important interfaces call external service apis to prevent timeout errors and use Hystrix to degrade the service. Later in the development, the use is still relatively little, mainly after catching exceptions, some code logic processing.

 

Four summarizes

I’m not done yet. I’ll continue in the next article