0%

问题

发现系统调用HTTPS接口时出现异常,异常信息如下

1
2
3
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: 
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target

排查

怀疑1: 接口提供方的证书过期了?(其实仔细看日志的话就可以排除这个可能)

操作: 通过本地浏览器打开对应url,浏览器显示正常的安全信息,证书也未过期,oracle的证书样例如下(例子中的根证书颁发机构为 DigiCert Global Root CA ),这时可以排除证书问题

阅读全文 »

本文主要对基于XML和基于注解配置声明式事务的执行过程进行介绍,因为Spring的事务是基于AOP的,所以最好了解一些AOP相关的基础内容,下面我们就开始进入正文

配置使用

我们使用一个功能,首先就是需要配置,这里我们写一个基于Mybatis的配置,dataSource相关的配置都忽略,直接看事务相关的配置

1
2
3
4
5
6
<!-- 声明使用的事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
<!-- 启用注解式声明事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />

这样配置后,在对应的方法上添加@Transactional注解即可启用事务,非常方便

原理

Spring的事务配置和使用是很简单的,但是我们一定不会满足于此,接下面我们就来分析一下上面这几行配置如何起到这么大的作用

阅读全文 »

对于多线程并发对数据的修改的情况,其实除了使用锁或者CAS机制之外,有的情况我们完全可以为每一个线程分配单独的数据,这个数量只能在对应的线程下才能访问到,这样就能避免资源的争抢

或者对于单次请求全局的一些信息,比如当前请求对应的用户信息,可以不通过参数的方式依次传递,而是在全局的一个地方维护,比如当请求进来时,就将当前用户的信息存储进去,但是因为我们的服务是多线程的,同时可能有很多的请求,所以需要用户信息有线程隔离的能力,不能访问到或覆盖了别的线程的用户信息

JDK提供的对应功能的类就是ThreadLocal

阅读全文 »

Redis的存储是基于内存的,这就有意味着,如果服务重启那么所有的数据都会丢失,这是我们不能接受的,为此,Redis提供了 RDB 与 AOF 两种持久化机制

简介

RDB: 对于RDB,我们可以把它理解一个定时的快照,就是每隔一段时间(或其他策略),它会创建一个当时所有数据的一个快照,默认存储到的文件为 dump.rdb

AOF: 因为RDB创建的是所有数据的快照,这点就决定了它不可能进行高频率的执行,但是如果不经常性的执行,那么当出现如服务器宕机等情况时,会丢失从上次快照到当前的所有操作数据。为了解决这个问题,AOF应运而生,它会在每次执行操作的时候,将这个操作命令进行持久化存储,默认存储到的文件为 appendonly.aof,这样恢复的时候,可以将 aof文件中的所有命令重新执行一遍,即可恢复数据

阅读全文 »

最近因为工作原因,学习了一下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实现的

阅读全文 »