fastdfs源码
⑴ Ubuntu10.04下,nginx添加fastdfs-nginx-mole,编译后启动nginx,只看见master进程,为什么
回复 1# nicole0169 应该是fastdfs扩展模块没有编译进nginx。请参照INSTALL文件说明。另外,你的nginx版本比较老,建议升级到最新的stable版本。
⑵ 如何安装FastDFS
Google了一下,流行的开源分布式文件系统有很多,介绍如下:
mogileFS:Key-Value型元文件系统,不支持FUSE,应用程序访问它时需要API,主要用在web领域处理海量小图片,效率相比mooseFS高很多。
fastDFS:国人在mogileFS的基础上进行改进的key-value型文件系统,同样不支持FUSE,提供比mogileFS更好的性能。
mooseFS:支持FUSE,相对比较轻量级,对master服务器有单点依赖,用perl编写,性能相对较差,国内用的人比较多
glusterFS:支持FUSE,比mooseFS庞大
ceph:支持FUSE,客户端已经进入了linux-2.6.34内核,也就是说可以像ext3/rasierFS一样,选择ceph为文件系统。彻底的分布式,没有单点依赖,用C编写,性能较好。基于不成熟的btrfs,其本身也非常不成熟。
lustre:Oracle公司的企业级产品,非常庞大,对内核和ext3深度依赖
NFS:老牌网络文件系统,具体不了解,反正NFS最近几年没发展,肯定不能用。
鉴于fastDFS是国人开发,也有国内的一些大公司在使用,so…
普通的文件架构其实一两年内也是没有问题的,但有句话叫未雨绸缪,于是决定折腾折腾。
源码下载:
寻求帮助:
一、安装libevent
fastDFS需要安装libevent比较新的版本,将本机的比较低的版本卸载了。
rpm -qa libevent
libevent-1.4.13-1.el6.x86_64
rpm -e --nodeps libevent
安装一个最新稳定版
wget
tar zxvf libevent-2.0.18-stable.tar.gz
cd libevent-2.0.18-stable
./configure
make && make install
为libevent创建软链接到/lib库下,64位系统对应/lib64
ln -s /usr/local/lib/libevent* /lib/
ln -s /usr/local/lib/libevent* /lib64/
二、安装FastDFS
wget
tar zxvf FastDFS_v3.06.tar.gz
cd FastDFS
./make.sh
./make.sh install
三、配置FastDFS
环境:
tracker server
192.168.1.5
storage server
192.168.1.51
192.168.1.52
1、配置并启动 tracker server
①配置 tracker.conf
mkdir /data/fastdfs
vim /etc/fdfs/tracker.conf
base_path=/data/fastdfs
②启动 tracker
/usr/local/bin/fdfs_trackerd /etc/fdfs/tracker.conf
③开机启动
vim /etc/rc.local
/usr/local/bin/fdfs_trackerd /etc/fdfs/tracker.conf
2、配置并启动 storage server
①配置 tracker.conf
mkdir /data/fastdfs
mkdir /data/images
vim /etc/fdfs/storage.conf
base_path=/data/fastdfs
store_path0=/data/images
tracker_server=192.168.1.5:22122
②启动 tracker
/usr/local/bin/fdfs_storage /etc/fdfs/storage.conf
③开机启动
vim /etc/rc.local
/usr/local/bin/fdfs_storage /etc/fdfs/storage.conf
3、为storage节点安装fastdfs-nginx-mole模块
①安装模块
安装Nginx详见:
需重新编译Nginx
wget
tar zxvf fastdfs-nginx-mole_v1.10.tar.gz
wget
tar zxvf nginx-1.2.0.tar.gz
cd nginx-1.2.0
./configure --prefix=/usr/local/nginx --add-mole=../fastdfs-nginx-mole/src
make && make install
cd ..
②配置
编辑nginx.conf
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
location /M00 {
alias /data/images/data;
ngx_fastdfs_mole;
}
......
}
给 storage 的存储目录做一个软连接
ln -s /data/images/data/ /data/images/data/M00
拷贝mod_fastdfs.conf 到 /etc/fdfs/
cp fastdfs-nginx-mole/src/mod_fastdfs.conf /etc/fdfs/
vim /etc/fdfs/mod_fastdfs.conf
base_path=/data/fastdfs
tracker_server=192.168.1.5:22122
store_path0=/data/images
启动nginx
/usr/local/nginx/sbin/nginx
四、使用FastDFS
1、上传文件
FastDFS安装包中,自带了客户端程序,通过程序可以进行文件上传。在使用这个客户端程序之前,首先需要配置client.conf,然后再进行文件上传及下载。
在tracker上修改客户端配置文件client.conf
vim /etc/fdfs/client.conf
base_path=/data/fastdfs
tracker_server=192.168.1.5:22122
vim a.html
This Is FastDFS Test.
上传文件
/usr/local/bin/fdfs_test /etc/fdfs/client.conf upload a.html
This is FastDFS client test program v3.06
Copyright (C) 2008, Happy Fish / YuQing
FastDFS may be copied only under the terms of the GNU General
Public License V3, which may be found in the FastDFS source kit.
Please visit the FastDFS Home Page /
for more detail.
[2012-04-29 12:42:53] INFO - base_path=/data/tracker, connect_timeout=30, network_timeout=60, tracker_server_count=1, anti_steal_token=0, anti_steal_secret_key length=0
tracker_query_storage_store_list_without_group:
server 1. group_name=group1, ip_addr=192.168.1.51, port=23000
server 2. group_name=group1, ip_addr=192.168.1.52, port=23000
group_name=group1, ip_addr=192.168.1.51, port=23000
storage_upload_by_filename
group_name=group1, remote_filename=M00/00/00/wKgBM0-cxs32qFyYAAAADigvbpc90.html
source ip address: 192.168.1.51
file timestamp=2012-04-29 12:42:53
file size=14
file crc32=674197143
file url:
storage_upload_slave_by_filename
group_name=group1, remote_filename=M00/00/00/wKgBM0-cxs32qFyYAAAADigvbpc90_big.html
source ip address: 192.168.1.51
file timestamp=2012-04-29 12:42:53
file size=14
file crc32=674197143
file url:
上传成功
试试用
访问看看吧。
看了几天了,还是有些地方不是很明白,暂时搁置,不能再浪费时间了。
⑶ 面试必问的epoll技术,从内核源码出发彻底搞懂epoll
epoll是linux中IO多路复用的一种机制,I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。当然linux中IO多路复用不仅仅是epoll,其他多路复用机制还有select、poll,但是接下来介绍epoll的内核实现。
events可以是以下几个宏的集合:
epoll相比select/poll的优势 :
epoll相关的内核代码在fs/eventpoll.c文件中,下面分别分析epoll_create、epoll_ctl和epoll_wait三个函数在内核中的实现,分析所用linux内核源码为4.1.2版本。
epoll_create用于创建一个epoll的句柄,其在内核的系统实现如下:
sys_epoll_create:
可见,我们在调用epoll_create时,传入的size参数,仅仅是用来判断是否小于等于0,之后再也没有其他用处。
整个函数就3行代码,真正的工作还是放在sys_epoll_create1函数中。
sys_epoll_create -> sys_epoll_create1:
sys_epoll_create1 函数流程如下:
sys_epoll_create -> sys_epoll_create1 -> ep_alloc:
sys_epoll_create -> sys_epoll_create1 -> ep_alloc -> get_unused_fd_flags:
linux内核中,current是个宏,返回的是一个task_struct结构(我们称之为进程描述符)的变量,表示的是当前进程,进程打开的文件资源保存在进程描述符的files成员里面,所以current->files返回的当前进程打开的文件资源。rlimit(RLIMIT_NOFILE) 函数获取的是当前进程可以打开的最大文件描述符数,这个值可以设置,默认是1024。
相关视频推荐:
支撑亿级io的底层基石 epoll实战揭秘
网络原理tcp/udp,网络编程epoll/reactor,面试中正经“八股文”
学习地址:C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂
需要更多C/C++ Linux服务器架构师学习资料加群 812855908 获取(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,Mysql,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享
__alloc_fd的工作是为进程在[start,end)之间(备注:这里start为0, end为进程可以打开的最大文件描述符数)分配一个可用的文件描述符,这里就不继续深入下去了,代码如下:
sys_epoll_create -> sys_epoll_create1 -> ep_alloc -> get_unused_fd_flags -> __alloc_fd:
然后,epoll_create1会调用anon_inode_getfile,创建一个file结构,如下:
sys_epoll_create -> sys_epoll_create1 -> anon_inode_getfile:
anon_inode_getfile函数中首先会alloc一个file结构和一个dentry结构,然后将该file结构与一个匿名inode节点anon_inode_inode挂钩在一起,这里要注意的是,在调用anon_inode_getfile函数申请file结构时,传入了前面申请的eventpoll结构的ep变量,申请的file->private_data会指向这个ep变量,同时,在anon_inode_getfile函数返回来后,ep->file会指向该函数申请的file结构变量。
简要说一下file/dentry/inode,当进程打开一个文件时,内核就会为该进程分配一个file结构,表示打开的文件在进程的上下文,然后应用程序会通过一个int类型的文件描述符来访问这个结构,实际上内核的进程里面维护一个file结构的数组,而文件描述符就是相应的file结构在数组中的下标。
dentry结构(称之为“目录项”)记录着文件的各种属性,比如文件名、访问权限等,每个文件都只有一个dentry结构,然后一个进程可以多次打开一个文件,多个进程也可以打开同一个文件,这些情况,内核都会申请多个file结构,建立多个文件上下文。但是,对同一个文件来说,无论打开多少次,内核只会为该文件分配一个dentry。所以,file结构与dentry结构的关系是多对一的。
同时,每个文件除了有一个dentry目录项结构外,还有一个索引节点inode结构,里面记录文件在存储介质上的位置和分布等信息,每个文件在内核中只分配一个inode。 dentry与inode描述的目标是不同的,一个文件可能会有好几个文件名(比如链接文件),通过不同文件名访问同一个文件的权限也可能不同。dentry文件所代表的是逻辑意义上的文件,记录的是其逻辑上的属性,而inode结构所代表的是其物理意义上的文件,记录的是其物理上的属性。dentry与inode结构的关系是多对一的关系。
sys_epoll_create -> sys_epoll_create1 -> fd_install:
总结epoll_create函数所做的事:调用epoll_create后,在内核中分配一个eventpoll结构和代表epoll文件的file结构,并且将这两个结构关联在一块,同时,返回一个也与file结构相关联的epoll文件描述符fd。当应用程序操作epoll时,需要传入一个epoll文件描述符fd,内核根据这个fd,找到epoll的file结构,然后通过file,获取之前epoll_create申请eventpoll结构变量,epoll相关的重要信息都存储在这个结构里面。接下来,所有epoll接口函数的操作,都是在eventpoll结构变量上进行的。
所以,epoll_create的作用就是为进程在内核中建立一个从epoll文件描述符到eventpoll结构变量的通道。
epoll_ctl接口的作用是添加/修改/删除文件的监听事件,内核代码如下:
sys_epoll_ctl:
根据前面对epoll_ctl接口的介绍,op是对epoll操作的动作(添加/修改/删除事件),ep_op_has_event(op)判断是否不是删除操作,如果op != EPOLL_CTL_DEL为true,则需要调用_from_user函数将用户空间传过来的event事件拷贝到内核的epds变量中。因为,只有删除操作,内核不需要使用进程传入的event事件。
接着连续调用两次fdget分别获取epoll文件和被监听文件(以下称为目标文件)的file结构变量(备注:该函数返回fd结构变量,fd结构包含file结构)。
接下来就是对参数的一些检查,出现如下情况,就可以认为传入的参数有问题,直接返回出错:
当然下面还有一些关于操作动作如果是添加操作的判断,这里不做解释,比较简单,自行阅读。
在ep里面,维护着一个红黑树,每次添加注册事件时,都会申请一个epitem结构的变量表示事件的监听项,然后插入ep的红黑树里面。在epoll_ctl里面,会调用ep_find函数从ep的红黑树里面查找目标文件表示的监听项,返回的监听项可能为空。
接下来switch这块区域的代码就是整个epoll_ctl函数的核心,对op进行switch出来的有添加(EPOLL_CTL_ADD)、删除(EPOLL_CTL_DEL)和修改(EPOLL_CTL_MOD)三种情况,这里我以添加为例讲解,其他两种情况类似,知道了如何添加监听事件,其他删除和修改监听事件都可以举一反三。
为目标文件添加监控事件时,首先要保证当前ep里面还没有对该目标文件进行监听,如果存在(epi不为空),就返回-EEXIST错误。否则说明参数正常,然后先默认设置对目标文件的POLLERR和POLLHUP监听事件,然后调用ep_insert函数,将对目标文件的监听事件插入到ep维护的红黑树里面:
sys_epoll_ctl -> ep_insert:
前面说过,对目标文件的监听是由一个epitem结构的监听项变量维护的,所以在ep_insert函数里面,首先调用kmem_cache_alloc函数,从slab分配器里面分配一个epitem结构监听项,然后对该结构进行初始化,这里也没有什么好说的。我们接下来看ep_item_poll这个函数调用:
sys_epoll_ctl -> ep_insert -> ep_item_poll:
ep_item_poll函数里面,调用目标文件的poll函数,这个函数针对不同的目标文件而指向不同的函数,如果目标文件为套接字的话,这个poll就指向sock_poll,而如果目标文件为tcp套接字来说,这个poll就是tcp_poll函数。虽然poll指向的函数可能会不同,但是其作用都是一样的,就是获取目标文件当前产生的事件位,并且将监听项绑定到目标文件的poll钩子里面(最重要的是注册ep_ptable_queue_proc这个poll callback回调函数),这步操作完成后,以后目标文件产生事件就会调用ep_ptable_queue_proc回调函数。
接下来,调用list_add_tail_rcu将当前监听项添加到目标文件的f_ep_links链表里面,该链表是目标文件的epoll钩子链表,所有对该目标文件进行监听的监听项都会加入到该链表里面。
然后就是调用ep_rbtree_insert,将epi监听项添加到ep维护的红黑树里面,这里不做解释,代码如下:
sys_epoll_ctl -> ep_insert -> ep_rbtree_insert:
前面提到,ep_insert有调用ep_item_poll去获取目标文件产生的事件位,在调用epoll_ctl前这段时间,可能会产生相关进程需要监听的事件,如果有监听的事件产生,(revents & event->events 为 true),并且目标文件相关的监听项没有链接到ep的准备链表rdlist里面的话,就将该监听项添加到ep的rdlist准备链表里面,rdlist链接的是该epoll描述符监听的所有已经就绪的目标文件的监听项。并且,如果有任务在等待产生事件时,就调用wake_up_locked函数唤醒所有正在等待的任务,处理相应的事件。当进程调用epoll_wait时,该进程就出现在ep的wq等待队列里面。接下来讲解epoll_wait函数。
总结epoll_ctl函数:该函数根据监听的事件,为目标文件申请一个监听项,并将该监听项挂人到eventpoll结构的红黑树里面。
epoll_wait等待事件的产生,内核代码如下:
sys_epoll_wait:
首先是对进程传进来的一些参数的检查:
参数全部检查合格后,接下来就调用ep_poll函数进行真正的处理:
sys_epoll_wait -> ep_poll:
ep_poll中首先是对等待时间的处理,timeout超时时间以ms为单位,timeout大于0,说明等待timeout时间后超时,如果timeout等于0,函数不阻塞,直接返回,小于0的情况,是永久阻塞,直到有事件产生才返回。
当没有事件产生时((!ep_events_available(ep))为true),调用__add_wait_queue_exclusive函数将当前进程加入到ep->wq等待队列里面,然后在一个无限for循环里面,首先调用set_current_state(TASK_INTERRUPTIBLE),将当前进程设置为可中断的睡眠状态,然后当前进程就让出cpu,进入睡眠,直到有其他进程调用wake_up或者有中断信号进来唤醒本进程,它才会去执行接下来的代码。
如果进程被唤醒后,首先检查是否有事件产生,或者是否出现超时还是被其他信号唤醒的。如果出现这些情况,就跳出循环,将当前进程从ep->wp的等待队列里面移除,并且将当前进程设置为TASK_RUNNING就绪状态。
如果真的有事件产生,就调用ep_send_events函数,将events事件转移到用户空间里面。
sys_epoll_wait -> ep_poll -> ep_send_events:
ep_send_events没有什么工作,真正的工作是在ep_scan_ready_list函数里面:
sys_epoll_wait -> ep_poll -> ep_send_events -> ep_scan_ready_list:
ep_scan_ready_list首先将ep就绪链表里面的数据链接到一个全局的txlist里面,然后清空ep的就绪链表,同时还将ep的ovflist链表设置为NULL,ovflist是用单链表,是一个接受就绪事件的备份链表,当内核进程将事件从内核拷贝到用户空间时,这段时间目标文件可能会产生新的事件,这个时候,就需要将新的时间链入到ovlist里面。
仅接着,调用sproc回调函数(这里将调用ep_send_events_proc函数)将事件数据从内核拷贝到用户空间。
sys_epoll_wait -> ep_poll -> ep_send_events -> ep_scan_ready_list -> ep_send_events_proc:
ep_send_events_proc回调函数循环获取监听项的事件数据,对每个监听项,调用ep_item_poll获取监听到的目标文件的事件,如果获取到事件,就调用__put_user函数将数据拷贝到用户空间。
回到ep_scan_ready_list函数,上面说到,在sproc回调函数执行期间,目标文件可能会产生新的事件链入ovlist链表里面,所以,在回调结束后,需要重新将ovlist链表里面的事件添加到rdllist就绪事件链表里面。
同时在最后,如果rdlist不为空(表示是否有就绪事件),并且由进程等待该事件,就调用wake_up_locked再一次唤醒内核进程处理事件的到达(流程跟前面一样,也就是将事件拷贝到用户空间)。
到这,epoll_wait的流程是结束了,但是有一个问题,就是前面提到的进程调用epoll_wait后会睡眠,但是这个进程什么时候被唤醒呢?在调用epoll_ctl为目标文件注册监听项时,对目标文件的监听项注册一个ep_ptable_queue_proc回调函数,ep_ptable_queue_proc回调函数将进程添加到目标文件的wakeup链表里面,并且注册ep_poll_callbak回调,当目标文件产生事件时,ep_poll_callbak回调就去唤醒等待队列里面的进程。
总结一下epoll该函数: epoll_wait函数会使调用它的进程进入睡眠(timeout为0时除外),如果有监听的事件产生,该进程就被唤醒,同时将事件从内核里面拷贝到用户空间返回给该进程。
⑷ java都需要那些技术
Java工程师需要学习的技术还是比较多的。
尤其是现在技术更新迭代比较快,需要不断学习掌握新的技术,给自身镀金才能在IT行业发展的较好。
下面列举出来一些需要掌握的技术:
1、理解Java面向对象思想
2、掌握开发中常用基础API
3、熟练使用集合框架、IO流、异常
4、能够基于JDK8开发
5、掌握流行关系型数据MySQL常见操作
6、熟练增删改查数据处理
7、掌握Java JDBC、连接池操作
8、掌握基本的JavaWeb基础知识JSP/Servlet/Vue等
9、具备基本的B/S结构软件开发能力
10、可以动手开发一个B/S架构的Web项目
11、掌握SSM框架技术
12、掌握使用Maven进行模块的开发
13、熟悉基本的Linux命令以及Linux服务器的使用
14、掌握高级缓存技术Redis的原理,并熟练使用
15、掌握Git、Nginx、Docker、Elasticsearch、SpringBoot、SpringCloud、RabbitMQ、分布式事务、JVM、JUC、Zookeeper、Dubbo、Nacos等技术
16、企业级开发项目
虽然需要学习掌握的技术比较多,但是坚信“只要功夫深铁杵磨成针”,加油!
⑸ 求java学习路线图
/*回答内容很长,能看完的少走一个月弯路,绝不抖机灵*/
提前预警:本文适合Java新手阅读(老手可在评论区给下建议),希望大家看完能有所收获。
废话不多少了,先了解一下Java零基础入门学习路线:
第一阶段:JavaSE阶段
变量、数据类型、运算符
二进制和十进制的转化
注释、单行注释、多行注释、文本注释、注释内容和字节码的关系
标识符、关键字、驼峰原则
变量的本质、内存画图、变量声明和初始化
变量的分类和作用域(局部变量、成员变量、静态变量)
常量和Final
基本数据类型介绍
整型变量和整型常量
浮点类型、float、double
char字符型、转义字符
boolean布尔型、if语句使用要点、布尔类型占用空间问题
运算符介绍
算数运算符(二元、自增、自减)
赋值和赋值运算符
关系运算符详解
逻辑运算符、短路运算符详解
位运算符详解
字符串连接符
条件运算符(三元运算符)
运算符优先级问题
自动类型转换详解
强制类型装换详解
基本数据类型装换常见错误、溢出、L问题
使用Scanner获取键盘输入
控制语句
控制语句和实现逻辑对应
if单选结构
if_elseif_else多选结构
switch语句_IDEA更换主题
循环_while
循环_for循环_dowhile
嵌套循环
break和continue语句_标签_控制语句底层原理
写一个年薪计算机_网络查问题的秘诀(重要)
个人所得税计算器软件
方法核心详解_天才思维模型教你高手学习思维模式
方法的重载
递归结构讲解_递归头_递归体
面向对象编程-基础
面向过程和面向对象的区别
类和对象的概述
类的属性和方法
创建对象内存分析
构造方法(Construtor)及重载
对象类型的参数传递
this关键字
static关键字详解
局部代码块、构造代码块和静态代码块
package和import详解
JavaDoc生成API文档
面向对象编程-进阶
面向对象的三大特性
面向对象之【封装(Encapsulation)】
访问权限修饰符
面向对象之【继承(Inheritance)】
Object类
方法重写Override
super关键字详解
重写equals()和toString()
继承中对象创建的内存分析
面向对象之【多态(Polymorphism)】
向上转型
向下转型
instanceof运算符
编译时和运行时详解
final修饰符
抽象类和抽象方法(abstrct)
接口的定义和实现
JDK8的接口新特性
接口应用:内部类比较器Comparable
内部类详解
Java的内存管理与垃圾回收
异常机制
异常的概述
异常的执行过程与分析
try-catch-finally捕捉异常
throw抛出异常
throws声明异常
异常继承体系
运行时异常和编译异常
自定义异常
Java常用类
Wrapper包装类
自动装箱和自动拆箱
包装类的源码分析
String类的使用与内存原理
String类的源码分析
StringBuffer
StringBuilder
字符串处理类性能分析
Date类
System类
DateFormat类
Calendat类
Math类
BigInteger类和BigDecimal类
Random类
枚举类
File类
常见的面试题讲述与分析
数据结构的概述
线性表
顺序表
链表
栈和队列
树
二叉树
二叉查找树
二叉平衡树
黑红树
图
冒泡排序
选择排序
递归
折半查找
集合和数组的联系和区别
集合框架体系
ArrayList的使用和源码分析
集合中使用泛型
LinkedList的使用和源码分析
HashSet的使用和源码分析
哈希表及原理
TreeSet的使用和源码分析
比较器Comparable和Comparator
HashMap的使用和源码分析
TreeMap的使用和源码分析
Iterator于ListIterator
Collections工具类
旧集合类Vector、Hashtable
集合总结和选择依据
泛型接口
泛型类
泛型方法
IO流的概念
IO流的分类及其原理分析
文件流FlieInputStream、FileOutputStream
缓冲流BufferedInputStream、BufferedOutputStream
数据流ObjectInputStream、ObjectOutputStream
序列化和反序列化
转换流InputStreamReader、OutputStreamWriter
打印流PrintWrite和PrintStream
数组流ByteArrayOutputStream、ByteArrayInputStream
使用IO复制文件夹
进程和线程
线程的创建与启动
创建线程的三种方式对比
线程的生命周期
线程控制
多线程的安全问题与解决办法
线程的同步:同步代码块
线程的同步:同步方法
线程的同步:Lock锁
线程的死锁问题
线程通信
Condition
线程的完整生命周期
线程池ThreadPoolExecutor
ForkJoin框架
ThreadLocal类
计算机网络基础知识
网络通信协议
OSI参考模型
TCP/IP参考模型
数据的封装与拆封原理解析
TCP协议
UDP协议
IP地址和端口号
URL和Socket
使用TCP编程实现登录功能
使用UDP编程实现客服系统
使用TCP编程实现文件上传
手写ArrayList
手写单链表
手写Linkedlist
手写HashMap
手写HashSet
最新并发集合类
生产者消费者模式扩展
Lock锁和Condition
ReadWriteLock
BlockingQueue
volatile关键字
多线程题目练习
JDK新特征
面试题详解
设计模式入门
面向对象设计七大原则
简单工厂模式
工厂方法模式
单例模式
原型模式
装饰模式
适配器模式
外观模式
数据结构算法
集合(容器)
IO流
多线程
网络编程
集合提升寻训练
多线程提升训练
设计模式
第二阶段:数据库
数据库基础知识
MySQL基础知识
MySQL8新特征
安装和卸载MySQL8
使用navicat访问数据库
SQL语言入门
创建数据库表
DML
修改删除数据库表
表的完整性约束
表的外键约束
DML扩展
基本select查询
where子句
函数
group by
having
SQL99-内连接查询
SQL99-外连接查询
SQL99-自连接查询
SQL92-连接查询
不相关子查询
相关子查询
分页查询
索引
事务及其特征
事务的并发问题
事务的隔离级别
存储过程
导入导出数据
JDBC概述
使用JDBC完成添加/更新/删除操作
使用JDBC完成查询操作
JDBC常用接口
使用PreparedStatement
使用事务完成银行转账
提取DBUtil工具类
使用Properties读写属性文件
日志框架log4j
开发员工管理系统
MySQL基础
MySQL 查询语句
数据库对象
JDBC
第三阶段:JavaEE阶段
web开发概述
B/S和C/S架构简介
HTTP协议
HTTP请求头和响应头
Tomcat安装使用
Tomcat目录结构
Servlet概述
Servlet快速入门
Servlet生命周期
读取配置文件信息
HttpServletRequest
HttpServletResponse
GET和POST区别
解决中文乱码
请求转发与重定向
绝对路径和相对路径
Cookie
Session
ServletContext
ServletConfig
JSP技术介绍
JSP的执行过程
scriptlet
表达式
声明
JSP指令元素
JSP动作元素
JSP隐式对象
JSP底层原理
九大内置对象
四个作用域
Servlet和JSP的关系和区别
MVC模式
合并Servlet
JavaScript概述与特点
JS基础语法
函数
数组
Math对象
String对象
Date对象
事件event
浏览器开发者工具
console
DOM和BOM
window
location
navigator
history
认识DOM
DOM获取元素
jQuery简介及快速入门
jQuery入口函数
jQuery对象与DOM对象互相转换
基本选择器
属性选择器
位置选择器
表单选择器
内容选择器
jQuery事件
jQuery动画效果
DOM操作-操作文本
DOM操作-操作属性
DOM操作-操作元素
直接操作CSS样式
操作CSS类样式
购物车案例
表单验证
正则表达式
EL介绍及使用
EL取值原理
EL隐含对象
EL逻辑运算
JSTL介绍-核心标签库
JSTL核心标签库
JSTL-格式标签库
Filter原理
Filter生命周期
Filter链
Filter登录验证
Filter权限控制
Listener概述及分类
Listener监听在线用户
Ajax异步请求和局部刷新的原理
使用原生Ajax验证用户唯一性
jQuery Ajax
JSON的格式和使用
主要JSON解析器
Jackson的使用
Jackson的实现原理
使用jQuery Ajax实现三级联动
使用jQuery Ajax实现自动补全
分页的意义
理解分页工具类
实现基本分页
实现带查询的分页
文件上传原理
文件上传API
实现文件上传
文件下载原理
文件下载响应头
实现文件下载
Servlet
JSP
JavaScript
jQuery
EL+JSTL+过滤器+监听器
Ajax和JSON
分页和文件上传/下载
第四阶段:框架阶段
MyBatis概述
MyBatis入门配置
基本的CRUD操作
核心配置文件详解
Mapper.xml基础详解
模糊查询
分页的实现及插件PageHelper的使用
动态sql+sql片段的使用
一对多、多对一的关系处理
注解的使用
一级缓存和二级缓存说明及使用
generator逆向工程使用
Spring框架简介
Spring官方压缩包目录介绍
Spring环境搭建
IoC/DI容器详解
Spring创建Bean的三种方式
scope属性讲解
Spring中几种注入方式
静态代理设计模式
动态代理设计模式
AOP详解
AOP中几种通知类型
AOP两种实现方式
自动注入
声明式事务
事务传播行为
事务隔离级别
只读事务
事务回滚
基于注解式配置
常用注解
Spring 整合MyBatis
i18n
Spring整合Junit
MVC架构模式
手写MVC框架
SpringMVC简介
SpringMVC运行原理
基于配置文件方式搭建环境
基于注解方式搭建环境
SpringMVC的跳转及视图解析器的配置
SpringMVC和Ajax的交互
Spring 参数注入
SpringMVC作用域传值
视图解析器
文件下载
文件上传
Spring拦截器/拦截器栈
登录状态验证
SpringMVC容器和Spring容器介绍
异常处理4种方式
SpringMVC5其他常用注解
Maven简介
Maven原理
Linux安装及注意事项
Maven项目结构
POM模型
Maven 中项目类型
创建WAR类型的Maven项目
scope属性可取值
SSM项目拆分演示
Maven的常见插件讲解
热部署
BootStrap概述
BootStrap栅格系统
BootStrap常用全局CSS样式
常用组件
常用JavaScript插件
RBAC概述
RBAC发展历史
基于RBAC的数据库表设计
URL拦截实现
动态菜单实现
密码学
MyBatis
Spring
SpringMVC
Maven
BootStrap
RBAC
第五阶段:前后端分离阶段
Spring Boot简介
Spring Boot实现Spring MVC
配置文件顺序及类型讲解
Spring Boot项目结构
Spring Boot 整合MyBatis
Spring Boot 整合Druid
Spring Boot 整合PageHelper
Spring Boot 整合logback
Spring Boot 整合JSP
Spring Boot 整合Thymeleaf
Spring Boot 开发者工具
Spring Boot 异常显示页面
Spring Boot 整合Junit4
Spring Boot 项目打包部署
Spring Boot 整合Quartz
Spring Boot 中Interceptor使用
Spring Boot Actuator
HikariCP
Logback简介
Logback依赖说明
Logback 配置文件讲解
Logback 控制台输出
Logback 文件输出
Logback 数据库输出
Spring Security简介
Spring Security架构原理
什么是认证和授权
基础环境搭建
自定义认证流程
UserDetailsService和UserDetails
PasswordEncoder
自定义认证结果
授权-访问路径匹配方式
授权-权限管理
基于注解实现权限管理
Thymeleaf整合Security权限管理
Rememberme 实现
退出实现
CSRF
Linux简介
VMWare安装及使用
Linux安装及注意事项
Linux目录结构及路径
Linux常用命令
VMWare常用配置
XShell安装及使用
Xftp安装及使用
JDK解压版配置步骤
Tomcat配置步骤
安装MySQL
WAR包部署
Docker简介
Docker与VM对比
Docker特点
Docker架构
Docker安装与启动
镜像加速器配置
Docker镜像操作常用命令
Docker容器操作常用命令
DockerFile
搭建本地镜像仓库
推送镜像到阿里云及本地仓库
Docker容器生命周期
Docker数据管理
Redis简介
Redis 单机版安装
Redis 数据类型介绍
Redis 常用命令
Redis 持久化方案
Redis 的主从搭建
Redis的哨兵搭建
Redis 的集群搭建
Spring Boot整合Spring Data Redis
Redis的缓存穿透
Redis的缓存雪崩
Redis的缓存击穿
vsCode和插件安装
webpack介绍
Vue项目创建
Vue模板语法
Vue条件渲染
Vue列表渲染
Vue事件处理
Vue计算属性
Vue Class与Style
Vue表单处理
Vue组件
Vue组件生命周期
Vue 路由配置
Vue Axios网络请求
Vue跨域处理
Vue Element
Mock.js
Swagger2简介
Springfox
Swagger2基本用法
Swagger-UI用法
Swagger2配置
Swagger2常用配置
Git的下载和安装
Git和SVN对比
Git创建版本库
Git版本控制
Git远程仓库
Git分支管理
Git标签管理
GitEE建库
GitEE 连接及使用
GitEE 组员及管理员配置
Spring Boot
Logback
Spring Security
Linux - CentOS 8
Docker
Redis
Vue
Swagger
Git/GitEE
第六阶段:微服务架构
分布式文件系统概述
FastDFS简介
FastDFS架构
Tracker Server
Storage Server
FastDFS安装
安装带有FastDFS模块的Nginx
Fastdfs-java-client的使用
创建Fastdfs-java-client工具类
实现文件上传与下载
KindEditor介绍
通过KindEditor实现文件上传并回显
AMQP简介
RabbitMQ简介
安装Erlang
安装RabbitMQ
RabbitMQ原理
Spring Boot 集成RabbitMQ
RabbitMQ的交换器
Spring AMQP的使用
Eureka简介
Eureka和Zookeeper 对比
搭建Eureka注册中心
Eureka 服务管理平台介绍
搭建高可用集群
集群原理
Eureka优雅停服
Ribbon简介
集中式与进程内负载均衡区别
Ribbon常见的负载均衡策略
Ribbon的点对点直连
Feign简介
Feign的请求参数处理
Feign的性能优化
配置Feign负载均衡请求超时时间
Hystrix简介
服务降级
服务熔断
请求缓存
Feign的雪崩处理
可视化的数据监控Hystrix-dashboard
Spring Cloud Gateway简介
Gateway基于配置文件实现路由功能
Gateway基于配置类实现路由功能
Gateway中内置过滤器的使用
Gateway中自定义GatewayFilter过滤器的使用
Gateway中自定义GlobalFilter过滤器的使用
Gateway中使用过滤器实现鉴权
Gateway结合Hystrix实现熔断功能
什么是分布式配置中心
创建配置中心服务端
创建配置中心客户端
基于Gitee存储配置文件
基于分布式配置中心实现热刷新
什么是消息总线
基于消息总线实现全局热刷新
ElasticSearch介绍
ElasticSearch单机版安装
ElasticSearch集群版安装
ElasticSearch索引管理
ElasticSearch文档管理
ElasticSearch文档搜索
SpringDataElasticSearch访问ElasticSearch
LogStash介绍
基于LogStash收集系统日志
分布式事务简介
分布式事务两大理论依据
分布式事务常见解决方案
LCN简介
TX-LCN的3种模式
LCN原理
LCN环境搭建及Demo演示
Nginx的简介
什么是正向代理、反向代理
Nginx的安装
Nginx配置虚拟主机
Nginx配置服务的反向代理
Nginx的负载均衡配置
Spring Session介绍
通过Spring Session共享session中的数据
通过Spring Session同步自定义对象
Spring Session的Redis存储结构
设置Session失效时间
Spring Session序列化器
MyBatis Plus简介
Spring整合MyBatis Plus
MyBatis Plus的全局策略配置
MyBatis 的主键生成策略
MyBatis Plus的CRUD操作
条件构造器EntityWrapper讲解
MyBatis Plus的分页插件配置
MyBatis Plus的分页查询
MyBatis Plus的其他插件讲解
MyBatis Plus的代码生成器讲解
MyBatis Plus的公共字段自动填充
简介
数据库切分方式
基本概念
MySQL主从配置
切片规则
读写分离
实现分库分表
FastDFS
RabbitMQ
Spring Cloud Netflix Eureka
Spring Cloud Netflix Ribbon
Spring Cloud OpenFeign
Spring Cloud Netflix Hystrix
Spring Cloud Gateway
Spring Cloud Config
Spring Cloud Bus
ELK
TX-LCN
Nginx
Spring Session
MyBatis Plus
ShardingSphere
第七阶段:云服务阶段
Kafka简介
Kafka架构
分区和日志
Kafka单机安装
Kafka集群配置
自定义分区
自动控制
Spring for Apache Kafka
Zookeeper简介和安装
Zookeeper 数据模型
Zookeeper 单机版安装
Zookeeper常见命令
ZClient操作Zookeeper
Zookeeper 集群版安装
Zookeeper 客户端常用命令
Zookeeper分布式锁
什么是分布式架构
什么是RFC、RPC
HttpClient实现RPC
RestTemplate
RMI实现RPC
基于Zookeeper实现RPC 远程过程调用
SOA架构介绍
Dubbo简介
Dubbo结构图
Dubbo注册中心
Dubbo 支持的协议
Dubbo 注册中心搭建
Spring Boot 整合 Dubbo
Admin管理界面
Dubbo 搭建高可用集群
Dubbo 负载均衡
Spring Cloud Alibaba Dubbo简介
基于Zookeeper发布服务
基于Zookeeper订阅服务
实现远程服务调用处理
Spring Cloud Alibaba Nacos简介
搭建Nacos服务器
基于Nacos发布|订阅服务
实现远程服务调用处理
Nacos Config配置中心
Spring Cloud Alibaba Sentinel简介
搭建Sentinel服务器
Sentinel-实时监控
Sentinel-簇点链路
Sentinel-授权规则
Sentinel-系统规则
@SentinelResource注解
持久化规则
Spring Cloud Alibaba Seata简介
搭建Seata服务器
Seata支持的事务模式-AT模式
Seata支持的事务模式-TCC模式
Seata支持的事务模式-Saga模式
Seata支持的事务模式-XA模式
SeataAT事务模式应用方式
SeataTCC事务模式应用方式
Kafka
Zookeeper
RPC
Dubbo
Spring Cloud Alibaba Dubbo
Spring Cloud Alibaba Nacos
Spring Cloud Alibaba Sentinel
Spring Cloud Alibaba Seata