对了本次的主题虽然是Servlet,但不全是Servlet,都是用servlet带出来的,比如现在
public DynamicThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
boolean waitForTasksToCompleteOnShutdown,
long awaitTerminationMillis,
@NonNull BlockingQueue<Runnable> workQueue,
@NonNull String threadPoolId,
@NonNull ThreadFactory threadFactory,
@NonNull RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, waitForTasksToCompleteOnShutdown, awaitTerminationMillis, workQueue, threadPoolId, threadFactory, handler);
this.threadPoolId = threadPoolId;
RejectedExecutionHandler rejectedProxy = (RejectedExecutionHandler) Proxy
.newProxyInstance(
handler.getClass().getClassLoader(),
new Class[]{RejectedExecutionHandler.class},
new RejectedProxyInvocationHandler(handler, rejectCount));
setRejectedExecutionHandler(rejectedProxy);
}
mybatis动态代理
protected T newInstance(MapperProxy<T> mapperProxy) {
//这里使用JDK动态代理,通过Proxy.newProxyInstance生成动态代理类
// newProxyInstance的参数:类加载器、接口类、InvocationHandler接口实现类
// 动态代理可以将所有接口的调用重定向到调用处理器InvocationHandler,调用它的invoke方法
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
问题: 一个接口方法,返回值相同,方法相同,参数为Person,现在有子类PersonMan和PersonWoman,如何对接口进行适配?
public class Person {
private String name;
private Integer age;
}
public class PersonMan extends Person{
private String character;
}
public class PersonWoman extends Person{
private String constellation;
}
在泛型类型中支持class等,以及省去参数转换的上界通配符<? extends E>:上界通配符,表明参数化类型可能是所指定的类型,或者此类型的子类;
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
如下
public interface PersonService {
public void queryPerson(List<? extends Person> list);
}
@Service
public class PersonServiceImpl implements PersonService{
@Override
public void queryPerson(List<? extends Person> list) {
System.out.println(JSONObject.toJSONString(list));
}
}
List<Person> list = new ArrayList<>();
//List<PersonMan> list = new ArrayList<>();
//List<PersonWoman> list = new ArrayList<>();
personService.queryPerson(list);
那么如果参数类型为注解呢?
@Override
public void queryPerson(List<? extends Person> list,Class<? extends Annotation> t) {
System.out.println(JSONObject.toJSONString(list));
System.out.println(cast.annotationType());
}
那么为什么上面的parsePutAnnotation不用呢?
NONONO,其实是用了的,只不过方法不同
private static final Set<Class<? extends Annotation>> CACHE_OPERATION_ANNOTATIONS = new LinkedHashSet<>(8);
static {
CACHE_OPERATION_ANNOTATIONS.add(Cacheable.class);
CACHE_OPERATION_ANNOTATIONS.add(CacheEvict.class);
CACHE_OPERATION_ANNOTATIONS.add(CachePut.class);
CACHE_OPERATION_ANNOTATIONS.add(Caching.class);
}
其实我就是看他的写的emoj,而且在caching这个注解里他包含了4种注解,然后统一进行管理的。
插播:Dbeaver中普通操作都会,安利一个类似idea的快捷键功能,Template--->SQL编辑器中可设置常用SQL,快捷键加Tab唤出.
国际化包含文本的国际化和时区的国际化
@Repository VS @NoRepositoryBean
回到cache相关中,在开启缓存时提示错误需要加入@Enablecahing注解,而在验证缓存注解时,在接口加了NoRepositoryBean,那么NoRepositoryBean又是什么?跟@Repository有何不同?
NoRepositoryBean:见名知意就是不需要创建的bean,在Springboot jpa中标识,雷同与不需要序列化的字段标识transient;
NoRepositoryBean用做标记当前接口或者类(抽象)不应该作为RepositoryBean被注册到Spring上下文,Springdata提供了自动代理的机制
JMS(java message service)JSR-914
1.JMS:用于应用程序之间,或在分布式系统中发送消息。而一些生产者,消费者,消息等不是消息队列的特指,而是JMS的所有特性。
2.AMQP:(Advanced Message Queuing Protocol)
消息队列协议,中文规范,消息代理(message brokers) 从发布者(publisher)亦称作生产者(producers)接受消息,根据
不同的路由规则(Routing Rule)把接受到的消息发送给处理消息的消费者(consumers);
3.kafka? 零拷贝? 哎嗨,重点来了
官网:https://kafka.apache.org/
Kafka是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用于大数据实时处理领域。
其实大多数的消息队列的实时性只能保持在秒级,而在银行是能够在纳秒之间的,kafka2.8.x之前是基于zookeeper的,
架构图
默认分区内存大小32M,每个批次大小是16K
1.批次数据满了才会发送,16K
2.linger.ms批次数据未满时,延迟发送时间
Sender数据拉取
同步vs异步发送
1.配置
2.连接集群
3.指定序列化类型
4.创建生产者
5.发送数据
6.关闭资源
分区自定义,合理使用资源,负载均衡
可配置类都要放到统一类管理
1.指定分区的情况
2.没有指定分区,带key,key的hash值与topic的分区值取模
3.没有指定分区,不带key,粘性分区,随机选择一个分区,尽可能一直使用该分区
自定义分区器:实现分区器接口
一般会说那个表名作为key
自定义分区器:
恰好达到批次大小就进行发送
导致数据延迟:
生产环境配置5-100ms之间
压缩类型snappy
提供生产者吞吐量
应答ack 0 1 -1
动态ISR replica.lag.time.max.ms默认30s,超出则踢出
数据完全可靠条件:
ACK级别设置为1 +分区副本大于等于2 +ISR应答最小副本数量大于等于2
要求可靠性
要求速度
默认值为int最大值
ack和重试数据
幂等性和事务:保证单分区单回话内不会重复
开启事务,必须开启幂等性
指定事务id
数据有序
单分区有序:
多分区有序:
数据乱序
kafka1.x前后差别:
是否开启幂等性区别:
其中一个出现异常则先缓存,后落盘
zookeeper中存放的信息
工具:prettyzoo
1、brokerid
2、主题
3.消费者信息
AR:是kafka中你那个所有分区副本的总称
ISR:leader和follower之间正常通讯的节点
除了基础知识点之外我最想看的就是kafka的零拷贝跟netty的关系。
DMA
在介绍零拷贝之前,我们先来看一个技术名词DMA(Direct Memory Access
直接内存访问)。它是现代电脑的重要特征之一,允许不同速度的硬件之间直接交互,而不需要占用CPU的中断负载。DMA传输将一个地址空间复制到另一个地址空间,当CPU
初始化这个传输之后,实际的数据传输是有DMA设备之间完成,这样可以大大的减少CPU的消耗。我们常见的硬件设备都支持DMA