Tomcat NioEndpoint浅析
NioEndpoint 是 Tomcat 中负责使用 NIO 方式进行网络通信功能的模块,它负责监听处理请求连接,并将解析出的字节流传递给 Processor 进行后续的处理 下面梳理一下主要的处理流程,如下图 创建Acceptor(默认1个),并启动在对应端口进行监听 创建Poller(多核下默认为2个)并启动,每个 Poller 在创建时会开启一个 Selector Acceptor 监听到连接后,将其转发注册到随机的一个 Poller 中 Poller 在获取到连接后,将其包装为 PollerEvent,并添加到其 events 列表中 Poller 在执行时,会循环获取 events,执行其 run方法 PollerEvent 执行时,会将其中的 SocketChannel 注册到selector中,监听对应事件 当有事件触发时,Poller 会将对应的连接转发给 Endpoint Endpoint 会创建对应的 SocketProcessor, 并将其提交到线程池中执行 SocketProcessor 会获取 Endpoint 中的 hanler进行处理 简化一...
Tomcat整体结构概览
这里主要介绍一下 Tomcat 的整体设计结构 整体结构 Tomcat 的整体结构如下 主要分为两大部分,连接器和容器 连接器 ProtocolHandler EndPoint EndPoint 负责进行 TCP 监听连接,解析之后将消息转发给Processor Processor Processor 进行应用层对应的解析,如HTTP1.1协议,为请求和响应生成对应的Tomcat 的 Request 和 Response 对象 Adapter Adapter 主要负责将 Tomcat 的 Request 和 Response对象转换为 Servlet 的 ServletRequest 和 ServletResponse 对象 容器 容器中也是分层的,从 Engine -> Host -> Context -> Wrapper,消息进行层层对位转发 Server.xml 下面看一个具体 Tomcat 的 serverl.xml配置信息对应一下 12345678910111213141516171819202122232425262728293031323334...
Java字节码结构
我们都知道java实现跨平台靠的是虚拟机技术,将源文件编译成与操作系统无关的,只有虚拟机能识别并执行的字节码文件,由各个操作系统上的jvm来负责执行,屏蔽了底层具体的操作系统。这里我们就来认识一下这个只有jvm才认识的字节码文件的真实样子。 为了节省空间,类文件中没有任何分隔符,各个数据项都是一个挨着一个紧凑排列的,所以其中无论是顺序还是数量等都是严格规定的,哪个字节代表什么含义,长度是多少,先后顺序如何,都不允许改变。下面我们先看一下类文件的整体结构: Class文件结构 其中常量、接口、字段、方法和属性在其中按各自的结构紧密排列,个数由其前面的数量字段决定。同时类文件中最小单位为1个字节,超过一个字节的数据以大端方式存储。 下面依次介绍其中的每个部分: 魔数 魔数是用来确定文件的类型是否是class文件,因为只靠文件扩展名来确定文件类型并不可靠。 这个魔数占文件的开始4个字节,为CA FE BA BE。(注意:这里的字面代表的是十六进制数,而不是ASCII码) 版本号 接下来的4个字节为class文件版本号,其中前两个字节表示的是次版本号,后两个字节表示的是主版本号(从4...
Spring 事件及异步方法使用
Spring 不仅为我们提供了IOC , AOP功能外,还在这个基础上提供了许多的功能,我们用的最多的可能就是 Spring MVC了吧,但是让我们来看下spring-context包,其中包含了缓存、调度、校验功能等等 这里主要想介绍一下Spring提供的观察者模式实现(事件发布监听)及异步方法执行,这些功能也都是基于AOP实现的 Spring 事件 观察者模式大家都了解,它可以解耦各个功能,但是自己实现的话比较麻烦,Spring为我们提供了一种事件发布机制,可以按需要发布事件,之后由监听此事件的类或方法来执行各自对应的功能,代码互相不影响,以后修改订单后续的逻辑时不会影响到订单创建,有点类似于使用MQ的感觉~ 比如在配置中心apollo项目中,在portal创建了app后会发送app创建事件,监听此事件的逻辑处将此消息同步到各个环境的adminsevice中,大家有兴趣可以看下相关代码 现在我们来看看具体如何使用:假设一个下单场景,订单创建成功后可能有一些后续逻辑要处理,但是和创建订单本身没有关系,此时就可以在创建订单完成后,发送一个消息,又相应部分的代码进行监听处理,避...
Spring AOP 使用及浅析
看过了前面的Spring Beans相关的 IOC 功能, 接下来我们来看看 AOP 是如何实现的 我们都知道 AOP 是通过动态代理来实现的, 但是代理这一步是如何实现的呢? 其实就是之前提到过的, 在Spring Bean的创建过程中, 实现BeanPostProcessor的接口可以对创建好的Bean进行修改替换等操作 123456789protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) { invokeAwareMethods(beanName, bean); Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); invokeInitMethods(beanName, wrappedBean, mbd); // 依次执行beanFactory中所有实现BeanPostProcessor的后置方法...
流计算-Flink笔记
一种被设计来处理无穷数据集的数据处理系统引擎 对实时产生的数据进行实时统计分析 电商大促时,统计当前下单量、金额 实时统计 App 中的埋点数据等 流计算相比批处理需要切分为窗口才能进行分组聚合处理 同时需要解决如下两个问题 正确性/完整性 exactly-once 处理无序、延迟数据的能力 Flink对流计算提供的支持 同时支持高吞吐、低延迟、高性能(spark支持高吞吐和高性能,strom支持低延迟高性能) 支持事件时间概念 支持有状态的计算 支持高度灵活的窗口 基于轻量级分布式快照实现容错 基于JVM实现独立的内存管理 save point(保存点) 流计算的流程 窗口 在处理无限流数据时, 如果需要对数据进行分组聚合操作,实时获取结果时, 则需要将数据分段到不同的窗口中,分别进行计算输出 窗口可分为 滚动窗口(时间驱动、数量驱动) 有固定间隔相等的连续窗口,每个窗口不会重复, 如每5分钟统计一次或每5个数据计算一次 滑动窗口(时间驱动、数量驱动) 有固定间隔相等的连续窗口,每个窗口之间可能有重叠,如每5分钟,统计前20分钟数据 ...
Dubbo扩展点加载使用简述
扩展点加载机制主要是为了实现接口和实现的解耦,接口的具体实现并不在代码中指定,而是通过通过外部配置实现,Dubbo的扩展点加载是对JDK的SPI扩展点加强而来,大家如果不了解JDK的SPI也没有关系,这里我们主要来看一下Dubbo的实现 在Dubbo的实现中,主要有三个注解,@SPI、@Adaptive和@Activate,下面我们来结合例子分别看一下它们的使用 首先我们来定义一个接口和几个对应的实现 123456// @SPI注解表示这是一个扩展点,可以有不同的实现// 指定实现时,其中的名字需要与配置文件中的key相同@SPI("simple")public interface DemoService { String echo(URL url, String s);} 123456public class SimpleServiceImpl implements DemoService { @Override public String echo(URL url, String s) { ...
自定义扩展线程池
线程池的基本使用 Executors框架提供的创建线程池的方法 123456// 固定线程数量的线程池Executors.newFixedThreadPool(5);// 对于添加的任务,如果有线程可用则使用其执行,否则就创建新线程Executors.newCachedThreadPool();// 创建只有一个线程的线程池Executors.newSingleThreadExecutor(); 它们内部实现都是使用了ThreadPoolExecutor,平时使用时我们最好是直接使用ThreadPoolExecutor,根据实际情况提供如下7个参数对线程池进行定义使用 配置参数 1234567int corePoolSize, // 核心线程数int maximumPoolSize, // 最大线程数long keepAliveTime, // 超出核心数线程的最大空闲存活时间TimeUnit unit, // 空闲存活时间的...
状态模式笔记
在介绍状态模式之前,我们先看个简单的例子 比如我们正常的网上购物的订单,对于订单它有许多个不同的状态,在不同状态下会有不同的行为能力,如状态有待支付、已支付待发货、待收货、订单完成等等,在整个订单流转过程中,由不同的事件行为导致它状态的变更,可以看下它简单的状态图 这些状态虽然不同,但是都是属于订单的状态,对应的行为也是订单的行为,在编码的过程中,一种写法是将这些行为(方法)都写到订单这个类或者类似OrderService这种类中,如 1234567891011121314151617public class OrderService { private OrderDao orderDao; public void pay(Long orderId) { Order order = orderDao.findById(orderId); // 下面逻辑也可以改成使用switch if (order.getStatus() == OrderStatus.WAIT_PAY) { ...
Drools入门使用
Drools是一款基于Java语言的开源规则引擎,通过drools特定的语法,将复杂多变的业务规则统一管理。 环境配置 一、使用maven创建项目 添加相关依赖,pom.xml如下 123456789101112131415161718192021222324<?xml version="1.0" encoding="UTF-8"?><project ...> <packaging>kjar</packaging> <dependencies> <dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version>7.27.0.Final</version> </depend...
