0%

最近因为工作原因,学习了一下Netty,这里写个笔记记录一下

Netty是什么呢?它是一款异步事件驱动的网络应用程序框架,使用它可以快速的开发出可维护的高性能的面向协议的服务器和客户端—《Netty实战》

这是有两个关键词是异步和事件驱动,先来简单介绍一下

异步是指什么呢?就是发送消息和接收消息是异步的,如调用发送方法后,进行的异步发送,你不知道到底发送出去了没有,如果想要知道结果怎么办呢?这时候可以设置回调函数,发送结果会通过回调函数传回来,当然,其实也可以阻塞同步等待结果,不过那可能就会影响其他数据的处理了

事件驱动呢,我理解就是接收数据等的时候,如在数据可以到达可读取的时候,IO线程会通知调用我们相应的方法进行数据处理流程

阅读全文 »

提到面向对象编程,我们想到的就是封装、继承、多态,但是其实这几个特性并不是只有面向对象语言才能实现,面向过程的C语言也是可以支持实现这三个特性的,下面我们来具体看下

封装

1
2
3
4
// point.h
struct Point;
struct Point* makePoint(double x, double y);
double distance(struct Point *p1, struct Point *p2);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// point.c
#include "point.h"
#include <stdlib.h>
#include <math.h>

struct Point {
double x, y;
};

struct Point* makePoint(double x, double y) {
struct Point* p = malloc(sizeof (struct Point));
p->x = x;
p->y = y;
return p;
}

double distance(struct Point* p1, struct Point* p2) {
double dx = p1->x - p2->x;
double dy = p1->y - p2->y;
return sqrt(dx*dx + dy*dy);
}
阅读全文 »

NioEndpoint 是 Tomcat 中负责使用 NIO 方式进行网络通信功能的模块,它负责监听处理请求连接,并将解析出的字节流传递给 Processor 进行后续的处理

下面梳理一下主要的处理流程,如下图

NioEndpoint

阅读全文 »

这里主要介绍一下 Tomcat 的整体设计结构

整体结构

Tomcat 的整体结构如下

主要分为两大部分,连接器和容器

阅读全文 »

我们都知道java实现跨平台靠的是虚拟机技术,将源文件编译成与操作系统无关的,只有虚拟机能识别并执行的字节码文件,由各个操作系统上的jvm来负责执行,屏蔽了底层具体的操作系统。这里我们就来认识一下这个只有jvm才认识的字节码文件的真实样子。

为了节省空间,类文件中没有任何分隔符,各个数据项都是一个挨着一个紧凑排列的,所以其中无论是顺序还是数量等都是严格规定的,哪个字节代表什么含义,长度是多少,先后顺序如何,都不允许改变。下面我们先看一下类文件的整体结构:

阅读全文 »

Spring 不仅为我们提供了IOC , AOP功能外,还在这个基础上提供了许多的功能,我们用的最多的可能就是 Spring MVC了吧,但是让我们来看下spring-context包,其中包含了缓存、调度、校验功能等等

这里主要想介绍一下Spring提供的观察者模式实现(事件发布监听)及异步方法执行,这些功能也都是基于AOP实现的

阅读全文 »

看过了前面的Spring Beans相关的 IOC 功能, 接下来我们来看看 AOP 是如何实现的

我们都知道 AOP 是通过动态代理来实现的, 但是代理这一步是如何实现的呢? 其实就是之前提到过的, 在Spring Bean的创建过程中, 实现BeanPostProcessor的接口可以对创建好的Bean进行修改替换等操作

1
2
3
4
5
6
7
8
9
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
invokeAwareMethods(beanName, bean);
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd);

// 依次执行beanFactory中所有实现BeanPostProcessor的后置方法,对Bean进行修改(*AOP创建返回代理处*)
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
阅读全文 »

一种被设计来处理无穷数据集的数据处理系统引擎

对实时产生的数据进行实时统计分析

  • 电商大促时,统计当前下单量、金额
  • 实时统计 App 中的埋点数据等

流计算相比批处理需要切分为窗口才能进行分组聚合处理

同时需要解决如下两个问题

  1. 正确性/完整性 exactly-once

  2. 处理无序、延迟数据的能力

阅读全文 »

扩展点加载机制主要是为了实现接口和实现的解耦,接口的具体实现并不在代码中指定,而是通过通过外部配置实现,Dubbo的扩展点加载是对JDK的SPI扩展点加强而来,大家如果不了解JDK的SPI也没有关系,这里我们主要来看一下Dubbo的实现

在Dubbo的实现中,主要有三个注解,@SPI@Adaptive@Activate,下面我们来结合例子分别看一下它们的使用

阅读全文 »

线程池的基本使用

Executors框架提供的创建线程池的方法

1
2
3
4
5
6
// 固定线程数量的线程池
Executors.newFixedThreadPool(5);
// 对于添加的任务,如果有线程可用则使用其执行,否则就创建新线程
Executors.newCachedThreadPool();
// 创建只有一个线程的线程池
Executors.newSingleThreadExecutor();

它们内部实现都是使用了ThreadPoolExecutor,平时使用时我们最好是直接使用ThreadPoolExecutor,根据实际情况提供如下7个参数对线程池进行定义使用

配置参数

1
2
3
4
5
6
7
int corePoolSize,                     // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 超出核心数线程的最大空闲存活时间
TimeUnit unit, // 空闲存活时间的时间单位
BlockingQueue<Runnable> workQueue, // 任务队列
ThreadFactory threadFactory, // 线程工厂,可以在此设置线程是否为守护线程等
RejectedExecutionHandler handler // 饱和策略,任务队列满且线程数达到最大线程数时触发
阅读全文 »