普通的项目非分布式项目中的技术点思考(学习随记)

学习路线

在学习Java的路程中,最开始学习JavaSe,在Java基础学完后,开始接触JavaWeb,开始接触框架,Spring框架,SpringBoot框架、数据库框架、在学习一下中间件,就可以完成工作中crud的基础操作,去实现功能了。
但如果一直crud,就无法进步,下一步,就应该更近一步的去学习。
设计模式、代码重构、架构设计、技术选型等等,需要不断深入学习。
有时候做的项目可能并不会涉及分布式,可能就是一些业务,但可能在业务上,也有值得去思考、去深入学习的地方。
普通的项目非分布式项目中的技术点思考(学习随记)_第1张图片

一个‘毫无技术含量’的单机系统能有什么技术?

下面是一个单机系统可能涉及的技术,客户端请求进Tomcat,之后进入系统业务代码,同时系统接入数据库DB,再接入一些如Redis、MQ这样的中间件。

普通的项目非分布式项目中的技术点思考(学习随记)_第2张图片

池化技术

在连数据库的时候,一般会配置一个数据库连接池,在配置连接池后,其实可以思考,为什么要去配置连接池?很简单,其实就是比例连接的频繁创建和销毁的开销,以达到复用的目的。这其实也可以再深入,为什么创建和销毁连接花销很大,其中就可以再去深入了解操作系统内核相关的知识。

同时,还可以引申出其他的池化技术,比如象池,线程池,内存池,理解这些池在项目中的用处。

多线程

多个线程共同执行任务时,如何提升性能?在使用锁时,理解锁优化,锁升级的过程。如何使用路由把不同的请求,仍给不同的线程池。优化,尽量做串行化无锁编程(比如把每个请求放入一个队列里,由线程去处理,一个线程池一个线程专门处理这些并发请求,这样做,比4个线程并行抢锁性能更高)。

异步处理

很多项目中的代码都是同步处理业务请求,但我们也应该考虑什么地方适合去异步处理任务。这个时候,我们可以深入去了解CompleteFuture在项目的运用。
比如,当一个前端http请求进入后端时,并不仅仅是接受请求,然后开始处理任务。但如果某个业务执行很慢,但请求又频繁,这样会导致多个线程阻塞,影响性能。这种时候就可以考虑使用CompleteFuture实现异步处理,通过回调的方法提高系统的响应速度和吞吐量。

ThreadLocal

将资源和线程绑定,实现无锁编程。
举个例子,比如在JavaWeb开发中,往往都会从Session中获取用户信息,这些信息需要在服务层或DAO层进行使用。为了避免在每个服务层或DAO层方法中都需要传递这些信息,我们可以使用ThreadLocal将这些信息保存在当前线程中,这样在整个线程中都可以轻松地访问这些信息,而不需要在方法间来回传递。例如:

public class UserContext {
    private static final ThreadLocal<UserInfo> userInfoThreadLocal = new ThreadLocal<>();

    public static void setUserInfo(UserInfo userInfo) {
        userInfoThreadLocal.set(userInfo);
    }

    public static UserInfo getUserInfo() {
        return userInfoThreadLocal.get();
    }

    public static void clear() {
        userInfoThreadLocal.remove();
    }
}

// 在方法中使用
public void doSomething() {
    UserInfo userInfo = UserContext.getUserInfo();
    // ...
}

在每个请求处理的时候,我们可以在拦截器中设置当前用户信息,例如:

public class UserInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        UserInfo userInfo = getCurrentUserInfo();
        UserContext.setUserInfo(userInfo);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserContext.clear();
    }

    private UserInfo getCurrentUserInfo() {
        // 从Session中获取用户信息
        return new UserInfo();
    }
}

在此之后,UserContext中的userInfoThreadLocal将会持有当前用户信息,并且每个线程都是线程安全的

缓存过滤

在销售系统中,可以使用缓存过滤无效购买请求,如何保证缓存和数据库一致性。

业务隔离

不同的线程池处理不同的业务

普通的项目非分布式项目中的技术点思考(学习随记)_第3张图片

你可能感兴趣的:(分布式,java,数据库)