Java课程大纲(详解)
2023-02-20 16:36:48 1 举报
AI智能生成
Java自学,整理
作者其他创作
大纲/内容
JDK:java开发工具包,针对Java开发人员,可以编译运行Java程序
JRE:java运行时环境,针对使用java程序的客户,可以运行字节码(.class),但不能编译Java源码
JVM:用来执行解释执行字节码文件(.class),但不能正确的执行
区别
JDK包含JRE,JRE包含JVM
联系
//
单行注释
/**/
多行注释
单行和多行注释的使用
标识符由数字(0~9)和字母(A~Z和a~z),美元符号($),下划线(_)以及Unicode字符集种符号大于0xC0的说有符号组合构成(各符号之间没有空格)
标识符的第一个符号为字母,下划线和美元符,后面可以是任何字母,数字,美元符号或下划线。
标识符
该类型只有两个字面值:true和false
布尔型
boolean
int
long
short
byte
float
double
char
class
interface
数据类型
if
else
do
while
for
switch
case
default
break
continue
return
try
catch
finally
流程控制
public
protected
private
final
void
static
strict
abstract
synchronized
volatile
native
修饰符
package
import
throw
throws
extends
implements
this
supper
instanceof
new
动作
true
false
null
goto
const
保留字
关键字
关键字,标识符
String name=\"张三\";
变量定义
1字节8位
字节型
2字节16位
短整型
4字节32位
整型
8字节64位
长整型
4字节32位浮点数
单浮点型
8字节64浮点数
双浮点型
浮点型
字符型
boolean(true,false)
一串字符
字符串型
表达式就是符号(如加号,减号)与操作数(如b,3等)的组合
+、-、*、/、%、++、- -
基本的算数运算符
+=、-=、*=、/=、%=
复合算数运算符
算数运算符
等于
==
不等于
!=
大于
>
小于
<
大于等于
>=
小于等于
<=
关系运算符
两个为真才是真,由一个为假则是假
与
&&
有一个为真就是真,两个为假则是假
或
||
取反
非
^
逻辑运算符
?:表达式的取决于条件的计算结果。如果条件为真,则表达式1的值,且表达式1的计算结果则为整个?:表达式的值。如果表达式的值。如果表达式1为假,则计算表达式2的值,表达式2的计算结果为整个?:表达式的值
?被称为三元运算符,因为它需要三个操作数
条件?表达式1:表达式2
条件运算符
运算符
变量,数据类型,运算符
在某些情况下,需要当某一条件满足时才执行响应代码,条件不满足则执行其他代码。
if (布尔表达式) {//布尔表达式为true时需执行的代码;}
单分支
if (布尔表达式) { //布尔表达式为true时需执行的代码; }else { //布尔表达式为false时需执行的代码; }
双分支
if(布尔表达式1){ //布尔表达式1为true时执行的代码 }else if(布尔表达式2){ //布尔表达式1为false但是布尔表达式2为true时执行的代码}else if(布尔表达式3){ //布尔表达式1和布尔表达式2为false但是布尔表达式3为true时执行的代码}else{ //布尔表达式1、布尔表达式2和布尔表达式3均为false时执行的代码}
多分支
if(布尔表达式1){ //布尔表达式1为true时执行的代码 if(布尔表达式2){ //布尔表达式1和布尔表达式2均为true时执行的代码 }else{ //布尔表达式1为true,但布尔表达式2均为false时执行的代码 } }else { //布尔表达式1为false时执行的代码}
嵌套if
分支
switch (date){ case 1: System.out.println(\"星期一\
switch分支与发放
分支语句(if,switch)
for(int x = 10; x < 20; x = x+1) { System.out.print(\"value of x : \" + x ); System.out.print(\"\\"); }
先判断后执行
for(类型 变量名:集合) { 语句块;}
forEach
while( x < 20 ) { System.out.print(\"value of x : \" + x ); x++; System.out.print(\"\\"); }
do{ System.out.print(\"value of x : \" + x ); x++; System.out.print(\"\\"); }while( x < 20 );
线执行在判断
do...while
循环语句(for,forEach,while,do...while)
作用于循环中,表示跳出当前循环
作用于循环中,表示跳过当前循环剩余的部分,进入到下一次循环
作用于方法中,表示结束该方法
特殊流程控制continuc,brcak使用
数组可以把一组相关的数据一起存放,并提供方便的访问(获取)方式;
数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。数组时一种将一组数据存储在单个变量名下的优雅方式
简介
作用
数组的简介及作用
数据类型 [] 数组名字 int[] a;数据类型 数组名字 [] int a[];
语法
Int[] ary0 = new int[10];//创建一个长度为10的连续空间。
声明数组的同时,根据指定的长度分配内存,单数组中元素值都为默认的初始化值;(动态创建)
声明数组并分配内存,同时将其初始化;
与前一种方式相同,仅仅只是语法相对简略;
创建
数组的创建及基本语法
for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + \" \"); }
使用for循环
遍历
int num = arrayC[3];
获取
数组元素的获取和遍历
冒泡排序
数组的排序算法(冒泡排序法)
Java入门基础
性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机,嵌入式开发,Linux/Unix等一般采用面向过程开发,性能是最重要的因素
优点
没有面向对象易维护,易复用,易扩展
缺点
面向过程
易维护,易复用,易扩展,由于面向对象有封装,继承,多态性的特性,可以设计出低耦合的系统,使系统更加灵活,更加易于维护
性能比面向过程低
面向对象
面向对象和面向过程概述
类内部
类内部,同一个包
类内部,同一个包,子类
类内部,同一个包,子类,任何地方
封装
接口可以继承接口,但用extends而不是implement
接口不能继承抽象类,抽象类可以实现(implement)接口。原因使接口的实现和抽象类的继承都要重写父类的抽象方法,而接口里只能有抽象方法,抽象类允许有抽象方法和非抽象方法
抽象类可以继承实体类
继承
//父类public class Base { protected void show() {}}//子类class Kid extends Base { public void show() { System.out.println(\" i am kid\"); }} public static void main( String[] args ) { Kid kid = new Kid(); Base base = kid; base.show(); }
允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性易不同的方式运作。这就意味着虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式给予调用。
多态
面向对象的三大特征
是对象的抽象
类
是对客观事物的抽象
对象
类和对象
成员变量使用
对于所有的类来说,类名的首字母因该大写。如果类名由若干单词,则后面的每个单词首字母大写。
类名
所有的方法名都因该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
方法名
源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记Java是大小写敏感的,)文件的后缀为.java(如果文件名和类名不相同则会导致编译错误)
源文件名
所有的Java程序都由public static void main(String[] args) 方法开始执行。{%note success no-icon %}在Java小程序中,applet小程序没有main()方法,是调用init()或者run()方法来启动。{%endnote}
主方法入口
四要素
方法的四要素及方法重载
构造器特征
信息的封装和隐藏
访问修饰符
package/import语句
类的继承
方法重写,重写与重载的区别
方法参数的传递
值传递和引用地址传递
Object简介及相关方法使用
this,super,abstract,static,final关键字
抽象类
接口
Java面向对象
API帮助文档使用
八种基本类型对应的包装类使用
String类,StringBuffer类,StringBuilder类
Date类,DateFormat类,Calendar类
Math类,Random类
Biginteger类,BigDecimal
Java常用包与类
java异常概述
处理机制
try...catch...finally
throw,throws
Java集合概述
Collection接口,List接口,Set接口
List接口的学习,Set接口的学习,TreeSet排序
Map接口
Collections工具类
泛型
迭代器
IO概述
File类
IO分类,InputStrcam,OutputStrcam
Beade,Writcr
对象序列化和反序列化
Java集合,IO
线程的概述
线程的创建与启动(Thread)
线程的创建与启动(Runnable)
线程的常用方法
线程的生命周期
线程同步Lock
线程的调度和通信
生产者和消费者模式
线程池
枚举
反射
注解
XML的基本语法
网络编程的概述及作用
TCP/IP模型
Socket和ServerSocket
Java高级
show databases
查看所有的数据库
create database 数据库命;
创建数据库
drop database 数据库名;
删除数据库
use 库名;
选择数据库use数据库名
show tables;
显示数据库中所有的表
NOT NULL
当前键值不能为空
DEFAULT NULL
默认值为null
INT(11)
字段为int类型且占用11位
COMMENT'备注内容'
位当前字段添加备注
PRIMARY KEY(ID)
ENGINE = INNODB DEFAULT CHARSET = UTF8;
设置数据库引擎为innodb并且默认编码方式为UTF-8.
创建一张表
desc user1
desc 表名;
显示表中字段
drop table user1;
drop table 表名;
删除表
show create database user1;
show create database 库名;
查看数据库的详细信息
alter table user1 modify age int(11);
alter table 表名 modify 字段 字段类型;
修改字段的类型
alter table user add age int(8);
alter table 表名 add 字段 字段类型;
添加新字的字段
alter table user add sex int(8) after age;
alter table 表名 add 字段 字段类型 after 字段;
添加字段到指定位置后
alter table user drop sex;
alter table 表名 drop 字段;
删除表中字段
alter table user change uid userid int(8);
alter table 表名 change 原字段名 新字段名 字段的类型;
修改指定的字段
操作表的结构常用指令
insert into 表名 value(值1,值2,值3);
增加数据
delete from user1 where id = 2;
delete from 表名 where 字段 = 值;
delet from user1;
delet from 表名
删除数据
update user1 set password = '123' where id = 3;
update 表名 set 字段1 = 值1,字段2 = 值2 where 字段3 = 值3;
更新数据
select * from user1;
select * from 表名;
select username from user1;
select 字段 from 表名;
select username from user1 where password = 123;
select 字段1 from 表名 where 字段2 = 值;
查询数据
select * from user1 order by id desc;
select * from 表名 order by 字段 排序关键词(desc 降序 \\ asc 升序)
多字段排序
排序查询
select distinct username = 'phone' from user1;
select distinct 字段 = 值 from 表名;
去重 distinct()
select sum(password) as sum_ from user1;
select sum(字段) as 显示名(课随便设置) 库名
统计总数 sum()
select count(*) from user1;
select count(字段) from 表名;
计算个数 count()
select avg(id) as id_avg from user1;
select avg(字段) as 查询命名 from 表名;
平均数 avg()
select max(id) from user1;
select max(字段) from 表名;
最大值 max()
select min(id) from user1;
select min(字段) from 表名
最小值 min()
常用函数查询
操作表中数据的常用指令
数据库常用语句
关联查询
inner join
内链接时一种映射关系,如果两张表都存在相同的内容,则回显示出来。(在数学中一般称为“交集”)
通过字段1进行来连接
table_a 用a代替,table_b用b代替连接使用table_a的pk和table_b的pk作为连接的基础经行连接
内链接
左连接
右连接
就是在左连接和右连接中间加一个union全连接 = 左连接+右连接+去重(union)
全连接
左连接不包含内连接(左表独有数据)
右连接不包含内连接(右表独有数据)
外连接|全连接 不包含内连接(全集-交集=两集各不同的数据)
mysql查询,mysql多表查询https://blog.csdn.net/fuijiawei/article/details/122432727
分组,就是将相同的分到一组,或者说融合;
group by
筛选相当与一个if(判断)
having
select 字段1,字段2,字段3,from 表名 group by password habving 判断条件;
分组数据查询
从第二个开始,显示后面三个数据
select * from 表名 limit 偏移量,数量;
分页数据查询
子查询,分组,排序,分页查询
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
原子性(Atomicity)
事务前后数据保持一致
一致性(Consistency)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
隔离性(Isolation)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
持久性(Durability)
ACID,是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。https://blog.csdn.net/dengjili/article/details/82468576
mysql事务,事务的ACID
设定为主键后,数据库自动建立索引,InnoDB为聚簇索引,主键索引列值不能为空(Null)。
主键索引(primary key)
唯一索引
一个索引可以包含多个列,多个列共同构成一个复合索引。
复合索引
Full Test(MySQL5.7之前,只有MYISAM储存引擎支持全文搜索)。全文索引类型为FULLTEXT,在定义索引的列上支持值的全文查找允许在这些索引列中查找重复值和空值,全文索引可以在Char,VarChar上创建
全文索引
MySQL在5.7之后的版本支持OpenGIS几何数据模型,MySQL在空间索引这方面遵循OpenGIS几何数据模型规则。
空间索引
在文本类型为char,varchar,text类列上创建索引时,可以指定索引列的长度,但是数值类型不能指定。
前缀索引
索引分类
大大提高数据查询速度
可以提高数据检索的效率,降低数据的io成本,类似于书的目录
可以通过索引对数据进行排序,降低数据的排序成本降低了CPU的消耗
被索引的列会自动进行排序,包括(单列索引)和(组合索引),只是组合索引的排序需要复杂一些。
如果按照索引列的循序尽心排序,对order不用语句来说,效率就会提高很多。
索引会占据磁盘空间。
索引虽然会提高查询效率,但是会降低更新表的效率,比如每次对表进行增删改查操作,MySQL不仅要保持数据还有保存或者更新对应的索引文件。
维护索引需要消耗数据库资源。
数据库中不是索引越多越好,而是仅为那些常用的搜索字段建立索引效果最佳!
综合索引的优缺点
索引的优缺点
show index from user1;
show index from 表名;
查看索引
字段 类型 primary key
创建主键索引
create index password_index on user1(password);
create index 索引名(自定义) on 表名(字段);
创建单例索引
create unique index img1_index on java1(img1);
create unique index 索引名(自定义) on 表名(字段);
创建唯一索引
create index 索引名(自定义) on 表名(字段1,字段2);
select * from user where name = ? select * from user where name = ? and age = ?select * from user where name = ? and sex = ?select * from user where name = ? and age = ? and sex = ?
最左前缀原则(如下四种都满足条件)
select * from user where name = ? and sex = ? and age = ?select * from user where age = ? and sex = ? and name = ?select * from user where sex = ? and age = ? and name = ?select * from user where age = ? and sex = ?…………等等
#可以使用复合索引:索引中包含的字段数都有,只是顺序不正确,在执行的时候可以动态调整为最前左缀select * from user where sex = ? and age = ? and name = ?select * from user where age = ? and sex = ? and name = ?#不可以使用复合索引:因为缺少字段,并且顺序不正确select * from user where sex = ? and age = ? select * from user where age = ? and name = ?select * from user where age = ?select * from user where sex = ?
MySQL引擎在执行查询时,为了更好利用索引,在查询过程中会动态调整查询直段的顺序!(也就是说,当条件中的字段全部达到复合索引中的字段时,可以动态调整字段顺序,使起满足最左前缀)
如下是不满足最左前缀条件(但是不是全部都不生效,如下解释)
在查询时能利用复合索引的查询条件如下
满足复合索引的查询的两大原则
创建复合索引
创建索引
索引语句
Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。
Hash索引仅仅能满足\"=\
Hash索引无法被用来避免数据的排序操作。
Hash素银不能利用部分索引键查询。
Hash索引在任何时候都不能避免表扫描。
Hash索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
Hash索引
B-Tree 索引是 MySQL 数据库中使用最为频繁的索引类型,除了 Archive 存储引擎之外的其他所有的存储引擎都支持 B-Tree 索引。不仅仅在 MySQL 中是如此,实际上在其他的很多数据库管理系统中B-Tree 索引也同样是作为最主要的索引类型,这主要是因为 B-Tree 索引的存储结构在数据库的数据检 索中有非常优异的表现。
B-Tree索引
使用时间:5.025s
使用时间:3.742s
B-tree和hash性能比较
MySQL索引使用数据结构主要有B-Tree索引和hash索引。https://blog.csdn.net/yb546822612/article/details/108659260
BTREE
InnoDB
MyISAM
MEMORY/HEAP
NDB
存储引擎,允许索引类型
mysql索引与引擎关系
对于哈市索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选着哈希索引,查询性能最快;其余大部分场景建议选着BTree索引。
索引的数据结构
myslq索引https://developer.aliyun.com/article/831250
https://blog.csdn.net/qq_53573029/article/details/123907172?spm=1001.2014.3001.5502
自己之前有写过
JDBC的学习
如邮政编码,设置为char(255)就明显多了,可以直接设置为char(6)就可以了
应该尽量把字段设置为NOTNULL,这样在将来执行查询的时候,数据库不用去比较NULL值
span style=\
不用设置过多的字段空间
选取最适用的字段属性
使用连接(JOIN)来代替子查询(Sub-Queries)
MySQL从4.0的版本开始支持union查询,它可以把需要使用临时表的两条或更多的select查询合并的一个查询中。在客户端的查询会话结束的时候,临时表会被自动删除,从而保证数据库整齐、高效。使用union来创建查询的时候,我们只需要用UNION作为关键字把多个select语句连接起来就可以了,要注意的是所有select语句中的字段数目要想同
使用联合(UNION)来代替手动创建临时表
尽管我们可以使用子查询(Sub-Queries)、连接(JOIN)和联合(UNION)来创建各种各样的查询,但不是所有的数据库操作都可以只用一条或少数几条SQL语句就可以完成的。更多的时候是需要用到一系列的语句来完成某种工作。但是在这种情况下,当这个语句块中的某一条语句运行出错的时候,整个语句块的操作就会变得不确定起来。设想一下,要把某个数据同时插入两个相关联的表中,可能会出现这样的情况:第一个表中成功更新后,数据库突然出现意外状况,造成第二个表中的操作没有完成,这样,就会造成数据的不完整,甚至会破坏数据库中的数据。要避免这种情况,就应该使用事务,它的作用是:要么语句块中每条语句都操作成功,要么都失败。换句话说,就是可以保持数据库中数据的一致性和完整性。事物以BEGIN关键字开始,COMMIT关键字结束。在这之间的一条SQL操作失败,那么,ROLLBACK命令就可以把数据库恢复到BEGIN开始之前的状态
事务
尽管事务是维护数据库完整性的一个非常好的方法,但却因为它的独占性,有时会影响数据库的新能,尤其是在很大的应用系统中,由于在事务执行过程中,数据库将会被锁定,因此其它的用户请求只能暂时等待直到该事务结束。如果一个数据库系统只有少数几个用户来使用,事务造成的影响不会成为一个太大的问题;但假设有成千上万的用户同是访问一个数据库系统,列如访问一个电子商务网站,就会产生比较严重的响应延迟。
具体操作
锁定表
锁定表的方法可以维护数据的完整性,但是它却不能保证数据的关联性。这个时候我们就可以使用外键。
使用外键
该对哪些字段建立索引?
使用索引
绝大多数情况下,使用索引可以提高查询的速度,但如果SQL语句使用不恰当的话,索引将无法发挥它应有的作用。
第一:最好是在相同类型的字段间进行比较的操作
第二:在建有索引的字段上尽量不要使用函数进行操作
第三:在搜索字符型字段时,我们有时会使用LIKE关键字和通配符,这种做法虽然简单但时以牺牲系统新能为代价的
注意的几个方面
优化得查询语句
1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库.备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用NULL。
优化方案
myslq优化https://blog.csdn.net/zhangbijun1230/article/details/81608252
数据链接池
手写ORM
数据库(mySQL)
Java Se核心基础
HTML基本标签使用
表格及表单标签
DIV标签
CSS的学习
CSS常用选择器
CSS常用样式表
CSS盒子模型
CSS布局,浮动
H5+CSS新特性
HTML+CSS
JavaScript的概述
JavaScript基础语法
JavaScript函数
JavaScript的DOM编程
定时器,考试
JQuery的概述
JQuery的基本选择器,属性选择器,过滤选择器
JQuery数组的迭代
JQuery操作dom
JQuery表单验证
正则表达式
JSON概述与使用
JSON字符串与JSON对象互相转换
JSON循环遍历
FastJSON使用
JavaScript+Jquery
Layui的初步认识
Layui栅格布局
LayUI常用的页面元素(颜色,图标,按钮,导航)
Laycr弹出层
日期与时间选择
分页组件
文件上传
模板引擎
表单
数据表格
Layui
web前端
Tomcat服务的安装与使用
Tomcat目录结构
Tomcat项目发布
Tomcat启动与关闭
Tomcat整合IDEA
Maven简介与概述
Maven下载安装及环境变量搭建
Maven本地仓库配置
Maven配置阿里云镜像
Maven常用的命令
Maven项目的目录结构
Maven整合IDEA
Java Web环境搭建
Servlet的概述及作用
Servlet的三种创建方式
Servlet的生命周期
HttpServletRequest,HttpServletResponse对象
Servlet参数的接收和编码处理
Servlet请求转发和重定向
会话技术(Cookie/Session)
Servlet三大域对象
JSP概述及作用
JSP组成部分
JSP的执行原理
JSP九大内置对象
JSP四大域对象
EL表达式
JSTL标签
监听器(Listener)域过滤器(Filter)
Ajax概述及原理
Ajax常用的实现方法
JSP+Servlet
使用:Servlet+JDBC+DBUtils+C3P0+Maven+Layui实现RBAC项目实战
项目
javaEE 企业级开发
对象关系映射(Object Relational Mapping,简称,ORM):是一种为了解决面向对象与关系数据库存在的互不匹配的问题的技术。
简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将Java程序中的对象自动持久化到关系数据库中
ORM思想
以前最流行的ORM框架
Hibernate
MyBatis是一款优秀的持久层框架
它支持定制化SQL,存储过程以及高级映射
MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集
概述
是目前最受欢迎的持久层ORM框架
MyBatis
JPA:本身是一种ORM规范,不是ORM框架,由各大ORM框架提供实现。(类似日志门面Slf4j)
常见的ORM框架
ORM及MyBatis概述
用于注册数据库连接
1.DriverManager
与数据库连接对象
2.Connection
操作数据库SQL语句的对象
3.Statement/PrepareStatement
结果集或一张虚拟表
4.ResultSet
JDBC有四个核心对象:
该对象中包含了执行SQL语句的所有方法。类似于JDBC里面的Connection
1.SqlSession对象
它将根据SqlSession传递的参数动态地生成需要执行地SQL语句,同时负责查询缓存的维护。类似于JDBC里面地Statemnt/PrepareStatemnt
2.Executor接口
3.MappedStatement对象
4.ResultHandler对象,用于返回的结果进行处理,最终得到自己想要的数据各式或类型。可以自定义返回类型
Mybatis也有四个核心对象:
对比
理解Mybatis的实现原理
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.11</version> </dependency>
1.在maven中构建配置文件
Mybatis入门配置
基本的CRUD操作
核心配置文件及Mapper.xml详解
Dao层开发及常用规则
动态Sql使用
一对多,多对一的关系处理
一级缓存和二级缓存说明及使用
分页的实现及插件PageHelper的使用
generator逆向工程使用
Mybatis
Spring Framework 是一个开源的Java/Java EE全功能栈(full-stack)的应用程序框架,以Apache License 2.0开源许可协议的形式发布,也有.NET平台上的移植版本。该框架基于 Expert One-on-One Java EE Design and Development(ISBN 0-7645-4385-7)一书中的代码,最初由Rod Johnson和Juergen Hoeller等开发。Spring Framework提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量的属性文件和帮助类。
Spring框架介绍
IOC/DI解偶合及实现原理
Spring的配置详解
SpringAOP与动态代理
AOP具体实现(XML和注解)
Spring-JdbcTemplete
Spring编程式事务与申明事务管理
Spring源码解析
Spring
MVC设计模式
Spring MVC概述和入门
Spring MVC的执行原理及运行流程
Spring MVC数据绑定
Spring MVC视图的跳转,往域对象传值
Spring MVC常用的注解
Spring MVC和Ajax通过JSON进行互交
Spring MVC+Restful+相关注解实现
Spring MVC上传文件/下载文件
拦截器的创建于配置
I18N国际化实现
SpringBoot自定义starters
Spring MVC
SpringBoot简介于入门
Spring和SpringBoot对比和介绍
SpringBoot的配置类和配置文件
SpringBoot核心开发
SpringBoot整合Web开发
SpringBoot整合日志
SpringBoot整合缓存
SpringBoot与安全
SpringBoot跨域请求
SpringBoot Stater原理
这个注解是SpringBoot最核心的注解,用在SpringBoot的主类上,标识这是一个Springboot应用,用来开启SpringBoot的各项能力。实际上这个注解是@Configuration,@EnableAutoConfiguration,@ComponentScan三个注解的组合。
@SpringBootApplication
允许SpringBoot自动配置注解,开启这个注解之后,SpringBoot就能够根据当前类路径下的包或者类来配置SpringBean
@EnableAutoConfiguration
用于定义配置类,指出该类是Bean配置的信息源,相当于传统的xml配置文件,一般加在主类上。如果有一些第三方库需要用到xml文件任然建议通过@Configuration类作为项目的配置主类——可以使用@ImportResource注解加载xml配置文件。
@Configuration
组件扫描。让Spring Boot扫描到Configuration类并把它加入到程序上下文。@ComponentScan注解默认就会配置标识符了@Controller,@Service,@Repository,@Component注解的类到Spring容器中
@ComponentScan
用于标注数据访问组件,及DAO组件使用@Repository注解可以确保DAO或者repositoriees提供异常转译,这个注解修饰的DAO或者repositories类会被ComponetScan发现并配置,同时也不需要它们提供XML配置项。
@Repository
一般用于修饰service层的组件
@Service
用于标注控制层组件(如struts中action),表示这是个控制器bean,并且是将函数的返回值直接填入HTTPX响应体中,是REST风格的控制器;它是@Controller和@ResponseBody的集合。
@RestController
表示该方法的返回结果直接写入HTTP response body中一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后会返回结果不会被解析为跳转路径,而是直接写入HTTP response body中,比如异步获取json数据,加上@responsebody后会直接返回json数据。
@ResponseBody
泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注
@Conmponent
相当于XML中的,放在方法上面,而不是类,意思是产生一个bean,并交给Spirng管理。
@Bean
byType方式。把配置好的bean拿来用,完成属性,方法的组装,它可以对类成员变量,方法及构造函数进行标注,完成自动装配的工作。当加上(required=false)时,就算找不到bean也不报错。
@AutoWired
当有多个同一类型的bean时,可以用@Qualifier(“name”)来指定。于@Autowired配合使用
@Qualifier
没有括号内内容的话,默认byName。与@Autowired干类似的事。
@Resource(name=\"name\
RequestMapping是一个用来处理请求地址映射的注解;提供路由信息,负责URL到Controller中的具体函数的映射,可用于类或方法上。用于类上,表示类汇总的所有响应请求的方法都是以该地址作为路径。
@RequestMapping
用在方法的参数前面。例:@RequestParam String a = request.getParamenter(\"a\")
@RequestParam
路径变量。参数与大括号里的名字一样要相同。例:RequestMapping(\"user/get/mac/{macAddress}\")public String getByMacAddress(@PathVariable String macAddress){ //do something;}
@PathVariable
Spring Profiles提供了一种隔离应用程序配置的方式,并让这些配置只能在特定的环境下生效。任何@Component或@Configuration都能被@Profile标记,从而限制加载它的时机。@Configuration@Profile(\"prod\")public class ProductionConfiguration{//...}
@Profiles
Spring Boot可以使用注解的方式将自定义的properties文件映射到实体bean中,比如config.properties文件@Data@ConfigurationProperties(\"rocketmq.consumer\")public class RocketMQConsumerProperties extends RocketMQProperties{private int consumeThreadMin = 20;private int consumeThreadMax = 64;private int consumeConcurrentlyMaxSpan = 2000;private int pullThresholdForQueue = 1000;private int pullnterval = 0;pricate int consumeMessageBatchMaxSize = 1;pricate int pullBatchSize =32;}
@ConfigurationProperties
注解指定该类是一个实体类,并映射到数据表
@Entity
注解指定要用于映射数据表名称(name=“user“意思是表名为”user“)
@Table(name = \"user\")
注解指定实体类的主键
@Id
SpringBoot的注解使用和作用
SpringBoot
Mybatis-Plus是Mybatis增强工具,只做增强,不作改变,简化开发,提高效率
快速入门
MP的简介与快速入门
可以作用在类上何属性上,放在类上,会对所有的非静态(non-static)属性生成Getter/Setter方法,放在属性上,就会对该属性生成Getter/Setter方法。并可以指定Getter/Setter方法的访问级别。
@Getter/@Setter
默认情况下,会使用所有份瞬态(non-transient)和非静态(non-static)字段来生成equals和hascode方法,也可以指定具体使用那些属性。
@EqualsAndHashCode
生成toString方法,默认情况下,会输出类名,所有属性,属性会按照顺序输出,已逗号分隔。
@ToString
无参构造器,部分参数构造器,全参构造器,当我们需要重载多个构造器的时候,Lombok就无能为力了。
@Data
常见注解
具体步骤
MP和SpringBoot的集成配置
MP和SpringBoot完成基本的CRUD
MP的分页插件
MP条件构造器Wrapper
MP代码生成器
Mybatis-Plus
Quartz任务调度简介
Quartz基本使用
Quartz核心类讲解
掌握Quartz触发规则
Quartz Trigger触发器
Quartz Job&JobDetai
Quartz Calendars日历讲解
JobListener监听器和TriggerListener监听器
Spring整合Quartz
Quartz
Shiro概述与入门
Shiro执行流程
Shiro.ini文件说明
权限URL配置
自定义Realm实现权限与授权
标签与权限注解
SSM+Shiro的集成配置
缓存机制
记住我功能的使用
单点登录以及其他应用场景
Shiro
Git的下载和安装
Git和SVN对比
Git创建版本库
Git版本控制
Git远程仓库
Git分支管理
Git标签管理
Git常用命令总结
GitHub简介与账号注册
Git与Github远程仓库配置
Git/Github
一个高定制化,身份认证,权限控制框架
Spring Security
SpringBoot+SpringMVC+Spring+Mybatis+Mybatis-Plas+Quartz+Git多模块电商项目
项目实战
Java EE 高级框架阶段
Oracle的概述,Oracle的安装,新建用户,授权,表空间
Oracle的DQL
Oracle的PL/SQL语句块(语句块,判断,循环)
Oracle的子程序(存储过程和函数)
事务,视图
索引,游标
Oracle调优
Oracle架构设计
Oracle
虚拟机介绍和应用场景
VMware的安装和使用
Linux/CentOS系统介绍
CentOS系统目录结构
CentOS常用命令
CentOS文件权限管理
CentOS环境搭建(jdk,tomcat,mysql)
LinuxShell编程
Linux运维指南
esc+:wq
保存并退出
startx
打开可视化界面
pwd
查看我们现在所在的目录位置
ifconfig
查看网络设备信息
free -f
检查(查看)服务器下的内存是否足够
mkdir 文件夹名字
新建文件夹
touch 文件名.文件类型
新建文件
rm 文件名.文件类型
删除文件
rm -r 文件夹名字
删除文件夹
git init
初始化本地仓库
cd ..
切换至该目录
git clone ..
拉取项目代码到指定位置
ls
查看当前项目所有文件
du-sh*
项目占用空间
cat ..
查看文件
yum
系统自带的软件管理器java8:yum install java-1.8.0-openjbk* -yopenjdk* -yjava -version: 查看版本号
which ..
存放位置
wget ..
来下载压缩包(安装Maven)构建项目
tar -zxvf ..
解压压缩包
help
查看帮助手册
.. install
安装依赖,构建
find -name '*jar'
查找jia包
cp ..(地址)
复制
mv 旧名 新名
改名字
nohup java-jar ..&
后台启动命令
jobs
查看任务
ps
查看所有进程ps -eflgrep 'java' : 只筛选出java进程
netstat
占用端口
curl ..
访问端口
sz ..
下载或上传命令
vim ..
vim编辑器,快速修改代码
cd ~
返回上级目录
ip add
查看系统网络设备信息
grep 6 筛选路径 > 导入筛选值
进行筛选,筛选有6的数字
文件下所有子文件夹里的图片全部到执行命令的文件夹的根目录
./程序名
运行程序
访问端口3344
curl localhost:3344
浏览器访问位置
firewall-cmd --list-ports
查看端口是否开放
开启端口3310
firewall-cmd --zone=public --add-port=3310/tcp --permanent
开启端口
具体符号
普通文件
灰色
目录文件
蓝色
可执行文件
绿色
压缩文件
红色
链接文件
浅蓝色
图片文件
粉红色
设备文件
黄色
颜色区分文件类型
Linux/CentOS
子主题
Niginx 安装简单,配置灵活
安装向导
防火墙里80端口有没有开
阿里云或腾讯云需要把安全组的80放开
检查
如果在网页用ip加端口打不开
安装
Nginx的简介和安装
停止执行文件
./nginx -s stop
启动
./nginx
修改端口位置
vim nginx.conf
重新启动
./nginx -s reload
cd /usr/local/nginx/sbin
文件启动位置
linux启动
docker run --name=nginx -d -p 4030:80 nginx
docker 启动
Nginx的原型图
Nginx架构模型
Nginx负载均衡
Nginx+Vsftpd文件服务器
Nginx实现反向代理服务器
Nginx详细配置信息
LVS+Keepalived+Nginx安装及配置
Nginx
Dubbo简介
Dubbo架构分析
Dubbo的入门案例
Dubbo-admin的安装和使用
Dubbo注册中心
Dubbo提供者以及配置优化
Dubbo消费者和配置优化
Dubbo高可用,Dubbo负载均衡
SpringBoot整合Dubbo
解释:Apache Dubbo是一款高性能Java RPC框架
Dubbo
NoSQL,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
Not Only SQL
解耦,没有太大的关联
方便扩展(数据之间没有关系,很好扩展!)
大数据量高性能(Redis一秒写8万次,读取11万次,NoSQL的缓存记录级,是一种细粒度的缓存,性能回比较高)
传统类型是多样性的(不需要事先设计数据库,随取随用)
传统RDBMS和NoSQL
NoSQL的特点
结构化组织
SQL
数据和关系都存在单独的表中操作,数据定义语言
基础的事务
关系型数据库遵循ACID规则
....
传统的RDBMS
代表着不仅仅是SQL
没有声明性查询语言
没有预定义的模式键值对存储,列存储,文档存储,图形数据库
最终一致性,而非ACID属性
非结构化和不可预知的数据
CAP定理
高性能
...
NoSQL
比较
什么是NoSQL
单线程
核心:redis是将所有所有的数据全部放在内存中的,所以说使用单线程去操作效率就是最高的,多线程(CPU上下分切换,耗时的操作)
同时设置多个值,如果存在一个值,就都不成功。如果不存在,就都成功,保证原子性
Redis不区分大小写命令
14
sudo docker run -p 6379:6379 --name redis -v /data/redis/redis.conf:/etc/redis/redis.conf -v /data/redis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes
docker启动Redis
redis-cli -p 6379
连接Redis
ctrl+c
退出Redis
Redis了解
Nosql简介和Redis的安装
Redis的数据模型
flushdb
清除当前数据库
FLUSHALL
清除全部数据库的内容
keys *
查看数据库所有的key
select 3
切换数据库
DBSIZE
查看数据库大小
6379
端口
move name 1
移除数据第一个
EXPIRE name 10
10秒后过期
type name
查看当前类型
incr views
views自加一
incrby views 10
views自加10
decr views
views自减一
decrby views 10
views自减10
ttl key3
过期
mest k1 v1 k2 v2 k3 v3
多数据存储
mset user:1:name zhangsan user:1:age 2
设置多个值
EXISTS key1
是否存在key1的值
APPEND key1 \"hello\"
追加字符串
STRLEN key1
截取字符串长度
sentnx mykey \"MongDB\"
如果存在mykey,创建失败
getset db redis
先get然后set。如果不存在值,则返回nill。如果存在值,获取原来的值,并设置新的值
String类似的使用场景:value除了是我们的字符串还可以是我们的数字!
计数器
统计多单位的数量
粉丝数
对象缓存存储
使用场景
小结
String命令
所有list命令都是用l开头的
LRANGE list 0 -1
获取全部的值
LPUSH list one
将一个或多个值,插入到列表头部(左)
Rpush list right
将一个或多个值,插入到列表尾部(右)
lpop list
将一个或多个值,移除到列表头部(左)
rpop list
将一个或多个值,移除到列表头部(右)
lindex list 1
通过下表获得list中某一个值
移除list中一个值“one”
lrem list 1 one
移除一个精确的值
保留小标 1 2
ltrim mylist 1 2
通过下表截取指定的长度,这个list已经被改变了,截断了
将下标为0,把值替换为item
lset list 0 item
将列表中指定下标的值替换为另外一个值,更新操作(不存在会报错,存在更新当前下标的值)
把other插入到world前面
linsert mylist before world other
将某个具体的value插入到列表中某个元素的后面
把new插入到world后面
linsert mylist after world new
如果key不存在,创建新的链表
如果key存在,新增内容
如果移除了所有值,空链表,也代表不存在!
在两边插入活着改动值,效率最高! 中间元素,相对来说效率会低一点~
消息排队
Lpush Rpop
消息队列
Lpush Lpop
栈
List命令
sadd myset hello
set集合中添加元素
smembers myset
查看set的所有值
存在:(integer)1
不存在:(integer)0
判断myset中有么有hello
sismember myset helo
判断某一个元素是不是在set集合中
scard myset
获取set集合中的元素个数
移除myset中元素hello
rem myset hello
移除set集合中的中元素
随机抽选myset集合的元素
srandmember myset
随机抽选集合中的元素
随机抽选2个myset集合中的元素
srandmember myset 2
随机抽选出指定个数的元素
随机删除myset中的元素
spop myset
随机删除一个集合中的元素
将myset中的wu元素移动到myset2里
smove myset myset2 wu
将一个指定的值,移动到另外一个集合
以key1为基准,来找key2与key1中不同的
sdiff key1 key2
差集(不同的)
以key1为基准,来找key2中与key1相同的元素
sinter key1 key2
交集(相同的)(共同好友)
以key1为基准,来找key2与key1存在的元素
sunion key1 key2
并集(存在的元素)
粉丝
共同好友
共同关注
共同爱好
二度好友
Set命令
Map集合,key-map!时候这个值是一个map集合!本质和String类型没有太大的区别,还是一个简单你的key-value!
基本了解
在myhash键field1值中添加元素kuangshen
hset myhash field1 kuangshen
添加一个具体的key-value
get一个key-value
hget myhash field1
查询一个具体的key-value
设置key field1 value 是hello,field2 value是 world
hmset myhash field1 hello field2 world
设置多个key-value
获取myhash中field和field2的值
hmget myhash field1 field2
获取多个字段值
hgetall myhash
获取全部的数据
hdel myhash field1
删除hash指定的key字段!对应的value值也就消失了!
hlen myhash
查看有多少key-value对
hkeys myhash
查看所有的key
hvals myhash
查看所有的value
myhash中field3 key的 value field3 加2
hincrby myhash field3 2
value做加法
myhash中field3 key的 value field3 减2
hincrby myhash field3 -2
value做减法
hash变更的数据user name age,尤其是用户信息之类的,经常变动的信息!
hash更适合对象的存储,String更适合string字符串存储
Hash命令
添加salary(薪水)为2500 姓名为小红
zadd salary 2500 xiaohong
添加用户
zrangebyscore salary -inf +inf
zrange salary 0 -1
从小到大依次排序
zrevrange salary 0 -1
从 大到小依次排序
zrangebyscore salary -inf +inf withscores
从最小到最大依次排序并打印出来
最小值到2500的排序
zrangebyscore salary -inf 2500 withscores
从最小值到到指定的值
删除有序集合中的一个salary 中的xiaohong
zrem salary xiaohong
删除一个集合
zcard salary
获取有序集合中的个数
获取1~3之间的成员数量
zcount myset 1 3
获取区间的成员数量
其余的一些API,通过我们的学习,剩下的如如果共工作需要,这个时候你可以查看官方文档
学习思路
set排序
存储班级成绩标
工资表排序
普通消息设置1,重要消息设置2,带权重进行判断! 加权
排行榜
Zset(有序集合)
按照salary从最小到最大依次排序
五大基本数据类型
朋友的定位,附近的人,打车距离计算?
Redis的Geo在Redis3.2版本就推出了!这个功能可以推算地理位置的信息,两地之间的距离,房源几里的人!
简述
添加国家为china 经度为116.40,维度为39.90 城市为北京
geoadd china:city 116.40 39.90 beijing
geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian
添加地理数据(两级步伐直接添加,我们一般会下载城市数据,直接通过java程序一次性导入!):有效经度从-180到180度,有效纬度从-85.051度到85.05112878
获取china的beijin与chongqing地理位置(经纬度)
Geopos china:city beijin chongqing
获取地理经纬度
国家中国,城市北京到上海的直线距离
m:表示米km:表示千米mi:表示英里ft:表示英尺
geodist china:city beijin shanghai km
两个位置的距离长度
查询经度110 纬度30 半径为1000km的所有城市名字
georadius china:city 110 30 1000 km
查寻具体的长度半径,查询城市
查询经度110 纬度30 半径为1000km的所有城市的经纬度
georadius china:city 110 30 1000 km withcoord
查询具体的长度半径,查询经纬
georadius china:city 110 30 1000 km withcoord count 1
查询北京1000km以内的城市,返回城市名
georadiusbymember china:city beijin 1000 km
通过城市来查询具体的城市
127.0.0.1:6379> geohash china:city beijin chongqing1) \"wx4fbxxfke0\"2) \"wm5xzrybty0\"
geohash china:city being chongin
hash,将该命令返回11个字符的Geohash字符串!
ZRANGE china:city 0 -1
查看所有的元素
移除北京
zrem china:city beijin
移除指定元素
附近找朋友
查距离长度
GEO
geospatial 地理位置
两组数做对比,基数(不重复的元素)
什么是基数?
Redis Hperloglog基数统计的算法!
优点:占用的内存是固定,2的64次方不同的元素的技术,只需要12kb内存!
Redis2.8.9版本就更新了Hyperloglog数据结构
创建元素a b c d f i g e
pfadd mykey a b c d f i g e
创建元素
查看元元素个数
Pfcount mykey
查看有多少元素
合并mykey 和mykey2成立新的键mykey(相同元素只出现一次)
pfmerge mykey3 mykey mykey2
合并元素
传统方法,set保存用户的id,然后就可以统计set中的元素数量作为标准判断!这个方式如果保存大量的用户id,就会比较麻烦! 我们的目的是为了计数,而不是保存用户id;
官方统计有0.81%的错误率!统计UV是任务,是可以忽略不记的
网页的UV(一个人访问一个网站多次,但还是算作一个人!)
Hyperloglog基数统计
Bitmaps位图
位存储
如果是打卡,sign的第0天(1天),0是没打卡,1是打卡:第一天打卡了
setbit sign 0 1
添加
搜索sign 第一天有没有打卡
getbit sign 0
查找
统计sign打卡了多少天
bitcount sign
统计,1有多少
统计用户信息,活跃,不活跃,登录,未登录,打卡,两个状态的,都可以使用Bitmaps
Bitmaps位图场景详解
三种特殊数据类型
Redis事务本质:一组命令的集合!一个数据中的所有命令都会被序列化,在事务执行过程中,或按照顺序执行!,一次性,顺序性,排他性,执行一些列的命令~
Reds单挑命令是保存原子性的,但是事务不保证原子性~
所有的命令在事务中,并没有直接被执行!只有发起执行命令的时候才会执行!Exec
Redis事务没有隔离级别的概念!
1.开启事务(multi)
2.入队命令(....)
3.执行事务(exec)
基本逻辑
从上到下依次执行
127.0.0.1:6379> multiOK127.0.0.1:6379(TX)> set k1 v1 QUEUED127.0.0.1:6379(TX)> set k2 v2QUEUED127.0.0.1:6379(TX)> get k2QUEUED127.0.0.1:6379(TX)> exec1) OK2) OK3) \"v2\"
正常执行
取消事务后,事务列队中命令都不会被执行
127.0.0.1:6379> multiOK127.0.0.1:6379(TX)> set k1 v1QUEUED127.0.0.1:6379(TX)> set k2 v2QUEUED127.0.0.1:6379(TX)> set k4 v4QUEUED127.0.0.1:6379(TX)> discardOK127.0.0.1:6379> get k4(nil)127.0.0.1:6379> get k1\"v1\"
放弃事务
先是命令错误,然后是执行事务报错
127.0.0.1:6379> multi OK127.0.0.1:6379(TX)> set k1 viQUEUED127.0.0.1:6379(TX)> set k2 v2QUEUED127.0.0.1:6379(TX)> set k3 v3QUEUED127.0.0.1:6379(TX)> getset k3(error) ERR wrong number of arguments for 'getset' command127.0.0.1:6379(TX)> set k4 v4QUEUED127.0.0.1:6379(TX)> set k5 v5QUEUED127.0.0.1:6379(TX)> exec(error) EXECABORT Transaction discarded because of previous errors.127.0.0.1:6379> get k5(nil)127.0.0.1:6379>
编译型异常(代码有问题!命令有错),事务中所有的命令都不会被执行!
127.0.0.1:6379> get k1\"v1\"127.0.0.1:6379> multiOK127.0.0.1:6379(TX)> incr k1QUEUED127.0.0.1:6379(TX)> set k2 v2QUEUED127.0.0.1:6379(TX)> set k3 v3QUEUED127.0.0.1:6379(TX)> get k3QUEUED127.0.0.1:6379(TX)> exec1) (error) ERR value is not an integer or out of range2) OK3) OK4) \"v3\"
运行异常(1/0),如果事务中存在语法性,那么执行命令的时候,其他命令是可以正常执行的(比如有10个命令,其中有一个运行异常,系统会不管者一个异常,执行其他没有异常的语句)所以不存在原子型
Redis的事务
Redis事务
很悲观,认为什么时候都会出现问题,无论做什么都会加锁!
悲观锁
很乐观,认为什么时候都不会出问题,所以不会上锁!更新数据的时候区判断一下,在此期间是否有人修改过这个数据,
获取version
更新的时候比较version
乐观锁
理论
127.0.0.1:6379> set money 100OK127.0.0.1:6379> set out 0OK127.0.0.1:6379> get money\"100\"127.0.0.1:6379> get out\"0\"127.0.0.1:6379> watch moneyOK127.0.0.1:6379> multiOK127.0.0.1:6379(TX)> DECRBY money 20QUEUED127.0.0.1:6379(TX)> INCRBY out 20QUEUED127.0.0.1:6379(TX)> exec1) (integer) 802) (integer) 20
正常执行成功
第一吸纳线程执行失败
127.0.0.1:6379> watch moneyOK127.0.0.1:6379> multiOK127.0.0.1:6379(TX)> DECRBY money 10QUEUED127.0.0.1:6379(TX)> INCRBY out 10QUEUED127.0.0.1:6379(TX)> exec(nil)127.0.0.1:6379>
第一线程
127.0.0.1:6379> get money\"80\"127.0.0.1:6379> set money 1000OK127.0.0.1:6379> get money\"1000\"
第二线程
1.如果发现事务执行失败,就先解锁
2.获取最新的值,再次监控,select version
3.对比监视的值是否发生了变化,如果没有变化,那么可以执行成功,如果变量执行失败就继续执行1
127.0.0.1:6379> unwatchOK127.0.0.1:6379> watch moneyOK127.0.0.1:6379> multiOK127.0.0.1:6379(TX)> DECRBY money 10QUEUED127.0.0.1:6379(TX)> INCRBY out 10QUEUED127.0.0.1:6379(TX)> exec1) (integer) 9902) (integer) 30
执行失败
值测试多线程修改值,使用watch可以当做redis的乐观锁操作!
Redis监视测试
Redis实现乐观锁
<dependencies> <!--导入jedis的包--> <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>5.0.0-beta1</version> </dependency> <!--存入数据Fastjson--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.33</version> </dependency> </dependencies>
1.导入对应的依赖
1.链接数据库
//Jedis 所有的命令就是我们之前学习的所有指令! System.out.println(jedis.ping()); System.out.println(\"清空数据\"+jedis.flushDB()); System.out.println(\"判断某个键是否存在:\"+ jedis.exists(\"username\")); System.out.println(\
2.操作命令
3.断开链接
输出 pong
public class TestPing { public static void main(String[] args) { //1.new Jedis 对象 Jedis jedis = new Jedis(\"192.168.238.128\
2.编码测试:
public class TestTX { public static void main(String[] args) { Jedis jedis = new Jedis(\"192.168.238.128\
使用事务
我们要使用Java来操作Redis
Jedis
SpringBoot查欧总数据库:Spring-data jpa jdbc mogodb redis!SpirngData也是和SpringBoot齐名的项目!说用:在SpringBoot2.x之后,原来使用jedis被替为lettuce?jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedis pool连接池!更像BIO模式lettuce:采用netty,实例可以在多个多线程中进行共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式
<!--操作Redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
1.导入依赖
# SpringBoot 所有的配置类,都有自动配置类 RedisAutoConfiguration# 自动配置类都会绑定一个properties配置文件 RedisProperties# 配置redisspring.data.redis.host=192.168.238.128spring.data.redis.port=6379
2.配置连接
@Autowired private RedisTemplate redisTemplate; @Test void contextLoads() { redisTemplate.opsForValue().set(\"wu\
3.测试
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version> 2.9.9</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version> 2.9.9</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version> 2.9.9</version> </dependency>
jackson出错导入maven包(正确)
整合测试
SpringBoot整合Redis
启动的时候,就是通过配置文件来启动的
查看狂神笔记
docker exec -ti redis12 redis-cli -h localhost -p 6379
位置:/etc/redis
进入配置
Redis Config详解
Redis是数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失,所以Redis提供了持久化功能!
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里,
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何io操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常的敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点就是最后一次持久化后的数据可能丢失。我们默认的就是RDB,一般情况不需要修改这个配置!
什么是RDB
RDB文件地址:/data/redis/data
RDB保存你的文件时dump.rdb文件
测试60s内修改5次key,就会触发rdb操作
save 60 5
1.serve的规则慢足的情况下,会自动出发RDB规则
2.执行flushall命令,也会出发我们的rdb规则
3.退出redis,会产生出发我们rdb文件!
备份就自动生成一个dump.rdb
出发机制
1.只需要将RDB文件放在我们redis启动目录就可以,redis启动的时候会自动检查dump.rdb恢复启动的数据!
127.0.0.1:6379> config get dir1)\"dir\"2)\"usr/local/bin\"
2. 查看需要存在的位置
1.适合大规模的数据恢复!
2.对数据完整性不高!
1.需要一定的时间间隔进程操作!如果redis意外宕机了,这个最后一次修改数据就没有的了!
2.fork进程的时候,会占用一定的内容空间!!
几乎就他默认的配置就够用了,但是我们还是需要去学习!
如何恢复RDB文件!
持久化之RDB(Redis DataBase)操作
一日志的形式来记录每一个写操作,将redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就是根据日志文件的内容将指令从前到后执行一次一完成数据的恢复工作
AOF保存的时appendonly.aof文件
将所有命令都记录下来,history,恢复的时候就把这个文件全部再执行一遍!
默认时不开起的,我们需要手动配置!我们只需要将appendonly改为yes启动aof
appendonly no
什么是AOF
持久化之AOF(Append Only File)操作
持久化
Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息,
微博,微信,关注系统
127.0.0.1:6379> SUBSCRIBE kuangshengsuoReading messages... (press Ctrl-C to quit)1) \"subscribe\"2) \"kuangshengsuo\"3) (integer) 1
订阅频道等待推送信息
127.0.0.1:6379> PUBLISH kuangshengsuo \
发布者腹部信息到频道
具体命令
Redis是使用C实现的,通过分析Redis源码里的pubsub.c文件,了解发布和订阅机制的底层实现,藉此加深对redis的理解。
通过SUBSCRIBE命令订阅某频道后,redis-server里维护一个字典,字典的键就是一个个频道!,而字典的值则是一个链表,链表中保存了所有订阅这个channel的客户端,SUBSCRIBE命令的关键,就是将客户端添加到给定channel的订阅链表中。
通过PUBLSH命令订阅者发送消息,redis-server会使用给定的频道作为键,在它所维护的channel字典中查找记录了订阅这个频道所有客户端的链表,遍历这个链表
微信:
原理
Redis发布订阅
Redis集群环境搭建
主从复制之复制原理
dai
RedisCluster集群搭建
Redis系能调优
SpringBoot整合Redis,RedisTemplete使用
Redis
高性能,高可靠性,分布式部署,支持事务,多语言开发,支持多种消息模式,支持SQL筛选,延迟消息等;
不具备海量数据处理的能力
RabbitMQ
JMS兼容性,支持多种消息模式,支持多种协议,安全性较高,与Spring框架的集成比较好;
性能的吞吐量相对较低
ActiveMQ
高吞吐量,高性能,高可靠性,分布式部署,支持海量数据和高并发等特性;
功能相对简单,不适用于事务性强的场景
Kafka
详细队列RabbitMQ,ActiveMQ,Kafka各自优缺点
1.RabbitMQ是一个开源的消息代理的队列服务器,用来通过普通协议在完全不同的应用之间共享数据。
2.RabbitMQ是使用Erlang语言来编写的,并且RabbitMQ是基于AMQP协议的。
Rrlang语言在数据交互仿方面性能优秀,有着和原生Socket一样的延迟,这也是RabbitMQ高性能的原因所在。
1.可靠性:RabbitMQ使用一些机制来保证可靠性,如持久化、传输确认、发布确认。
2.灵活的路由:在消息进入队列之前通过Exchange来路由消息的。对于典型的路由功能,RabbitMQ已经提供了一些内置的Exchange来实现。针对更复杂的路由功能,可以将多个Exchange绑定在一起,也通过插件机制实现自己的Exchange。
3.消息集群:多个RabbitMQ服务器可以组成一个集群,形成一个逻辑Broker。
4.高可用:队列可以在集群中的机器上进行镜像,是的在部分结点出问题的情况下队列仍然可用。
5.多种协议:RabbitMQ支持多种消息队列协议,比如STOMP、MQTT等等。
6.多语言客户端:RibbitMQ几乎支持所有常用语言,比如Java、.NET、Ruby等等。
7.界面管理:RabbitMQ提供了一个易用的用户界面,是的用户可以监控和管理消息Broker的许多方面。
8.跟踪机制:如果消息异常,RabbitMQ提供跟踪机制,使用者可以找出发生了什么。
9.插件机制:RabbitMQ提供了许多插件,来从多方面进行扩展,也可以编写自己的插件
特点
RabbitMQ简介
RabbitMQ环境搭建
简单模式是最简单的消息模式,它包含一个生产者、一个消费者和一个队列。生产者想队列里发送消息,消费者从队列中获取消息并消费。
简单模式
gognz 模式是指向多个互相竞争的消费者发送信息的模式,它包含一个生产者、两个消费者和一个队列。连个消费者同时绑定到一个队列上去,但消费者获取消息处理耗时任务时,空闲的消费者冲队列中获取并消费消息
工作模式
发布/订阅模式是指同时向多个消费者发送信息的模式(类似广播的形式),它包含一个生产者、两个消费者、两个队列和一个交换机。两个消费者同时绑定到不同的队列上去,两个队列绑定到交换机上去,生产者通过发送消息到交换机,所有消费者接收并消费消息
发布/订阅模式
路由模式时可以更具路由键选择性给多个消费者发送消息的模式,它包含一个生产者,两个消费者,两个队列和一个交换机,两个消费者同时绑定到交换机上去,生产者发送消息到交换机,交换机通过路由键转发到不同队列,队列绑定的消费者接收并消费消息。
路由模式
通配符模式可以根据路由键匹配规则选择性给多个消费者发送消息的模式,它包含一个生产者,两个消费者,两个队列和一个交换机。两个消费者同时绑定到不同的队列上去,两个队列通过路由键匹配规则绑定到交换机上去,生产者发送消息到交换机,交换机通过路由键匹配给这转发到不同队列,队列绑定的消费者接收并消费消息。
通配符模式
RabbitMQ常用消息模式介绍
RabbitMQ消息发送原理
Spring集成RabbitMQ消息队列
SpringBoot集成RabbitMQ消息队列
RabbitMQ使用场景及面试刨析
解释:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的,高可靠的消息发布于订阅服务
分布式事务产生的原因
分布式事务理论模型
2PC模型
TCC模型
本地事务表
MQ消息事务
GTS集成和使用
TCC实现
分布式事务
支付宝支付
微信支付
易宝支付
银联支付
在线支付
Mycat的简介和安装
Mycat架构模型
Mycat概念详解
Mycat主键自增
Mycat读写分离
Mycat分库分表
Mycat性能调优
Mycat权限控制
Mycat
分布式链路追踪
D:\\Student\\SpringCloudAlibabadown\\apache-skywalking-apm-bin\\bin\\statup.bat
启动路径
UIQ前端(web监控页面)的jar包和配置文件
wepapp
后台应用的jar包,以及它的依赖jar包,里边又一个server-starter-*.jar就是启动程序
oap-libs
启动后台应用程序的配置文件,是使用的各种配置
config
各种启动脚本,一般使用脚本startup.*来启动web页面和对应的后台应用
oapService.*:默认使用的后台程序的启动脚本;(使用的是默认模式启动,还支持其他模式,个模式区别见,启动模式)
oapServiceinit.*:使用init模式启动;在此模式下,OAP服务启动亿执行初始化工作,然后退出
oapServiceNoInit.*:使用 no init模式启动;在此模式下,OAP服务器不进行初始化。
webappServic.*:UI前端的启动脚本;
statup.*:组合脚本,同时启动oapService.*:webappService.*脚本;
bin
skywalking-agent.jar:代理服务jar包
config:代理服务启动时使用的配置
plugins:包含多个插件,代理服务器时会加载改目录下的所有插件(实际是各种jar包)
optional-plugins:可选插件,当需要支持某种功能时,比如SpringCloud Gateway,则需要吧对应的jar包拷贝到plugins目录下;
agent
文件解释
skywalking-oap-server服务启动后会暴露11800和12800两个端口,分别为收集监控数据的端口11800和接受前端请求的端口12800,修改端口可以修改config/application.yml
启动成功后会启动两个服务,一个是skywalking-oap-server,一个时skywalking-web-ui
过去3分钟内服务平均响应时间超过1秒
过去2分钟服务成功率低于80%
过去3分钟内服务响应时间超过1s的百分比
服务实例在过去2分钟内平均响应时间超过1s,并且实例名称与正则表达式匹配
过去2分钟内端点平均响应时间超过1秒
过去2分钟内数据库访问平均响应时间超过1秒
过去2分钟内端点关系平均响应时间超过1秒
告警规则
Rule name:规则名称,也是在告警信息中显示的唯一名称,必须以rule结尾,前缀可自定义
Metrics name:度量名称,取值为oal脚本中的变量名,目前只支持long,double和int类型。
Include names:该规则租用与哪些实体名称,比如服务名,终端名(可选,默认为全部)
Exclude name:该规则不用于哪些实体名称,比如服务名,终端名(可选,默认全部)
Threshold:阈值
Pariod:多久警告规则需要被核实一下,这是一个时间窗口,与后端部署环境时间相匹配
Count:在一个Period窗口中,如果values超过Threshold值(按op),打到Count值,需要发送警报
Silence period:在时间N中触发警报后,在TN->TN + period这个阶段不警告。默认情况下,它的Period一样,这意味着相同的警告()在同一个Metrics name拥有相同的id在
告警规则配置项的说明
D:\\Student\\SpringCloudAlibabadown\\apache-skywalking-apm-bin\\config\\alarm-settings.yml
告警位置:
SkyWalking告警功能
skywalking
自定义邮件
Dubbo+Zookeeper+SpringBoot+Spring+Mybatis+Mybatis-Plus+Nginx+Redis+RabbitMQ分布式项目实战
实战项目
分布式
服务限流降级
适配Spring Cloud服务注册与发现标准,默认集成了Ribbon的支持
服务注册与发现
支持分布式系统中的外部化配置,配置更该时自动刷新
分布式配置管理
基于Spring Cloud Stream为微服务应用构建消息驱动能力
消息驱动能力
使用@GlobalTransactional注解,高效并且对业务零侵入地解决分布式事务问题
阿里云提供的海量,安全,低成本,高可靠的云存储服务,支持在任何应用,任何时间,任何地点存储和访问任意类型的数据
阿里云对象存储
提供妙级,精准,高可靠,高可用的定时(基于Cron表达式)任务调度服务。同时提供分布式的任务
分布式任务调度
覆盖全球的短信服务,友好,高效,智能的互联化通讯能力,帮助企业迅速搭建客户触达通道
阿里云短信服务
主要功能
Spring Cloud Alibaba 简介
(不推荐)Eureka
Zookeeper简介和安装
Zookeeper概念解释
Zookeeper数据模型
Zookeper原生操作Zookeeper
ZClient操作Zookeeper
使用Zookeeper实现配置文件中心
Zookeeper节点类型
Zookeeper分布式锁
Zookeeper
Consul
它是一个Nacos Server,可以为服务提供者和服务xiao
服务注册中心Nacos Server
服务消费者Nacos Client
服务提供者Nacos Client
可以实现服务注册中心
Nacos服务注册中心
一个更易于构建云原生应用的动态服务发现(Nocos Discovery),配置管理(Nacos Config)和服务管理平台
注册中心
配置中心
服务管理平台
具体
什么是Nacos
服务发现和服务健康检测
动态配置服务
动态DNS服务
服务及元数据管理
Nacos的关键特性包括:
结合负载均衡器的权重机制,设置的权重(1~100)越大,给的流量就越多
权重
Nacos Client会通过发送REST请求的方式向Nacos Serve注册自己的服务,提供自身的元数据,比如ip地址,端口等信息。Nacos Server接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中。
服务注册
在服务注册后,Nacos Client会维护一个定时心跳来持续通知Nacos Server,说明服务一直处于可用状态,防止被剔除,默认5s发送一次心跳
服务心跳
Nacos Server服务集之间会互相同步服务实例,用来保证服务信息的一致性。leader raft
服务同步
服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面注册额服务清单,并且缓存在Nacos Client本地,同时会在Nacos Client本地开启一个定时任务定时拉取服务端最新的注册表信息更新到本地缓存
服务发现
Nacos Server会开启一个定时任务用来检测注册服务实例和健康情况,对于超过15s没有收到客户端心跳的实例会将它的healthy属性为false(客户端服务时不会发现),如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)
服务健康检查
健康实例数 除以 总实例数 < 保护阈值(就会把不健康实例拿出来用)
保护阈值设置值必须在0-1之间
雪崩保护
核心功能
图解
启动了Nacos的客户端,不加也能运行,方便看
@EnableDiscoveryClient
具体注解
具体学习
server: port: 8020 #应用名称(nacos会将该名称当作服务名称)spring: application: name: order-service cloud: nacos: server-addr: 127.0.0.1:8848 discovery: username: nacos password: nacos name
先确定端口,然后注册服务
Nacos Client搭建
D:\\Student\\SpringCloudAlibabadown\acos\\bin\\startup.cmd
运行Nacos
单独部署
https://ghproxy.com/https://github.com/alibaba/nacos/releases/download/1.4.1/nacos-server-1.4.1.tar.gz
下载Nacos,版本为1.4.1
nacos8849 nacos8850 nacos8851
应为要部署多个服务,所以要搭建多个服务文件
#*************** Spring Boot Related Configurations ***************#### Default web context path:server.servlet.contextPath=/nacos### Default web server port:server.port=8849
#*************** Config Module Related Configurations ***************#### If use MySQL as datasource:spring.datasource.platform=mysql### Count of DB:db.num=1
### Connect URL of DB:db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTCdb.user.0=nacosdb.password.0=nacos
打开
修改conf\\application.properties的配置,使用外置数据源 要使用mysql5.7+(包括5.7)
#it is ip#example192.168.120.131:8849192.168.120.131:8850192.168.120.131:8851
ip:port
添加mysql文件
创建mysql数据库,sql文件位置:conf\acos-mysql.sql
JAVA_OPT=\"${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m\"
将2g改为512兆
如果出现内存不足:修改启动脚本(bin\\startup.sh)的jvm参数
shutdown.cmd shutdown.sh startup.cmd startup.sh[root@localhost bin]# ./startup.sh
运行
官方推荐Nginx反向代理
集群部署
具体搭建
server: port: 8021 #应用名称(nacos会将该名称当作服务名称)spring: application: name: stock-servic-8021 cloud: nacos: server-add: 127.0.0.1:8848 discovery: username: nacos password: nacos# - `spring.application.name`代表当前应用的名称;#- `spring.cloud.nacos.server-addr`代表Nacos服务端的地址;#- `spring.cloud.nacos.discovery.username`# `spring.cloud.nacos.discovery.password`代表Nacos服务端的登录用户名和密码。# 相同的服务特征
application.yaml
具体代码
(推荐)Nacos
服务注册中心
@RibbonClients(value = { //这里的name给的是nacos服务名称 @RibbonClient(name = \"stock-service\
使用RibbonClients
权重取值范围在(1~10)权重越大,分配到的流量越多(访问人数也就越多)
直接在Nacos设置权重
通过权重去设置负载均衡
修改默认负载均策略
自定义负载均衡策略
@Bean// 添加负载均衡的注解 @LoadBalanced public RestTemplate restTemplate(RestTemplateBuilder builder){ RestTemplate restTemplate = builder.build(); return restTemplate; }
在Aplication中添加
@Autowired RestTemplate restTemplate; @RequestMapping(\"/add\") public String add(){ System.out.println(\"下单成功\"); String msg = restTemplate.getForObject(\"http://stock-service/stock/reduct\
在实现类中使用
-Dserver.port=8022
添加(设置端口)
点击Copy Configration
在运行中Runing
添加多服务
使用轮询
@Configurationpublic class RibbonRandomRuleConfig { //方法名一定要交iRule @Bean public IRule iRule(){ return new RandomRule(); }}
1.在启动类Application外添加一个包
stock-service: ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
2.在Application.yaml中添加
使用权重实现负载均衡
Ribbon(提供多种负载均衡)
LoadBalancer(只提供轮询负载均衡)
服务调用
(不推荐)Feign
@FeignClient(name = \"stock-service\
1.创建一个接口
@EnableFeignClients
2.在主启动类添加注解
快速使用
使用Configuration会配置作用所有的服务提供方
1.全局配置
在接口添加 configuration = FeignConfig.class
使用只想针对一个服务进行配置,就不要加@Configuration
# springboot默认的日志级别是info,feign的debug日志级别就不会输入# 只输出com.wu.feign里面的日志logging: level: com.wu.feign: debug
# Feign日志局部配置feign: client: config:# 使用服务名 product-service: loggerLevel: BASIC
使用配置文件
2.局部配置
OpenFeign的日志配置
通过Options可以配置连接时间和读取超时时间,Options的第一个参数是连接的超时间(ms),默认值是2s;第二个请求处理超时时间(ms),默认是5s
全局配置
# Feign日志局部配置feign: client: config:# 使用服务名 product-service: loggerLevel: BASIC# 连接超时时间,默认2s connectTimeout: 5000# 请求处理超时时间,默认5s readTimeout: 3000
# 连接超时时间,默认2s connectTimeout: 5000# 请求处理超时时间,默认5s readTimeout: 3000
yml中配置
OpenFeign超时时间配置
public class CustomFeignInterceptor implements RequestInterceptor { Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public void apply(RequestTemplate requestTemplate) { //Todo requestTemplate.header(\"xxx\
在启动同目录下编写包
1.编写拦截包
@RestController@RequestMapping(\"/product\")public class ProductController {// 端口注入 @Value(\"${server.port}\") String port; @RequestMapping(\"/{id}\") public String get(@PathVariable Integer id) throws InterruptedException { Thread.sleep(2000); System.out.println(\"查询商品\"+id); return \"查询商品\"+id+\":\"+port; }}
2.有一个类来进行拦截
地址添加的是准备拦截的地址
requestInterceptors[0]: com.wu.intercptor.feign.CustomFeignInterceptor
3.在application.yaml添加
实例
OpenFeign自定义拦截器
OpenFeign
服务调用2
(不推荐)Hystrix
resilience4j
负载不均
缺乏自我保护
缺乏容错机制
线程池满
耦合过重
Load飙高
缓存穿透
消息投递过快,导致消息处理挤压
分布式系统需要的问题
https://sentinelguard.io/zh-cn/docs/introduction.html
解释:把流量作为切入点,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性
sentinel解决服务雪崩
@SentinelResource
java -jar sentinel-dashboard-1.8.0.jar
java -Dserver.port=8847-jar sentinel-dashboard-1.8.0.jar
个人启动端口备占,换端口
启动jar包
D:\\Student\\SpringCloudAlibabadown
-Dcsp.sentinel.dashboard.server=consoleIp:port
配置启动参数
访问时间,访问量,响应时间
实时监控
流量控制,服务降级,热点,权限
簇点链路
应对洪峰流浪:秒杀,大促,下单,订单回流处理
消息型场景:削峰填谷,冷热启动
付费系统:根据使用流量付费
API Gateway:精准控制API流量
任何应用:探索应用中运行的满程序块,进行限制
流控规则
降级规则
热点规则
系统规则
权限规则
集群流控
机器列表
控制台
控制台运行
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
链接位置
resource
流控效果
controlBhavior
阈值
count
阈流阈值类型,QPS模式(1)或并发线程数模式(0)
grade
流控效果(直接拒绝/WarmUp/匀速+排队等待),不支持按调用关系限流
limitApp
调用关系限流策略:直接,链路,关联
stategy
[ { \"resource\": \"/testA\
2.nacos配置中心流控规则
在Nacos中持久化
(推荐)sentinel
限流
如积分
一般在弱依赖中使用
降级
解决方法:
服务降级
(不推荐)Zuul
(可以用,不推荐)Zuul2
直接查看SpringCloud中文文档
必须在同一个group(分组名称)里面
(推荐)gateway
服务网关
(不推荐)Config
Nacos-config配置中心
服务配置
(不推荐)Bus
服务总线
微服务
可以理解为一组数据的存储结构
什么是数据结构
数据结构的元素之间存在一对一线性关系,所有结点都最多只有一个直接前趋结点和一个直接吼继结点。常见的有数组,队列,链表,栈
线性结构
各个结点之间具有多个对应关系,一个结点可能有多个直接前趋结点和多个直接吼继结点。常见的有多维数组,广义表,树结构和图结构等
非线性结构
数据元素之间逻辑关系的数据结构,这里的逻辑关系是指数据元素的前后间关系,与数据在计算机中的存储的位置无关
逻辑结构
存储顺序是连续的,在内存中用一组地址连续的存储单元依次存储线性表的各个数据元素
顺序存储
在内存中的存储元素不一定是连续的,用任意地址的存储单元存储元素,元素结点存放数据元素以及通过指针指向相邻元素的地址信息
链式存储
除建立存储结点信息外,还建立的附加的索引表来表示结点的地址。索引表由若干索引项组成
索引存储
又称Hash存储,由节点的关键码值决定节点的存储地址
散列存储
指数据的逻辑结构在计算机存储空间中的存放形式称为数据的物理结构,也叫做存储结构
物理结构(存储结构)
数据结构分类
数组可以说是最基本的数据结构。数组一般用来存储相同类型的数据,可通过数组名和下标进行数据的访问和更新。数组中元素的存储时安装先后顺序进行的,同时在内存中也是按照这个顺序进行连续存放。数组相邻元素之间的内存地址的间隔一般技术数据累心的大小。
数列(Array)
队列就是栈的兄弟结构,与栈的后进先出对应,队列是一种先进先出相对应,队列是一种先进先出的数据结构。顾名思义,队列的数据存储是如同排队一般,先存入的数据先被压出。常与栈一同配合,可发挥最大的实力
队列(Queue)
栈是一种比较简单数据结构,常用一句话描述其特性,后进先出。栈本省是一个线性表,但是在这个表中是有一个口子允许数据的进出。栈的常用操作包括入栈push和进栈pop,对应于数据的压入和压出。还有访问栈顶数据,判断栈是否为空和判断栈的大小等。由于栈后进先出的特性,常可以作为数据操作的临时容器,对数据的顺序进行调控,与其它数据结构结合可获得灵活的处理。
栈(Stack)
数作为一种树状结构,其数据节点之间的关系也如大叔一样,将有限个节点根据不同层次关系进行排列,从而形成数据与数据之间的父子关系。常见的数的表示形成更接近“倒挂的数”,因为它根朝上,叶朝下。树的数据存储在节点中,每个节点有零个或者多个子节点。没有父节点的节点在最顶端,成为根节点;没有非根节点有且只有一个父节点;每个非根节点有可以分为多个不相交的子数。这意味着树具备层次关系的,父子关系清晰,家庭血缘关系明朗;这也是数树与图之间主要的区别。
出去最后一层结点,其它层的结点树都达到最大值;同时最后一层的结点都是按照从左到右依次排布
完全二叉树
除了最后一层,其它层都结点都有两个子结点
满二叉树
二叉排序树:是一棵空树,或者:若它的左子树不空,则左子树上所有结点值均小于它的根结点的值;若它的右子树不空,则右子树所有结点的值均大于它的根节点的值;它的左,右也分别为二叉排序树。
树的高度:结点层次的最大值
平衡因子:左子树高度-右子树高度
平衡二叉树又称为AVL数,它是一棵二叉排序树,具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
平衡二叉树的产生是为了解决二叉排序树在插入时发生线性排列的现象。由于二叉排序树本身为有序,当插入一个有序程度十分高的序列时,生成的二叉排序树会持续在某个方向的子树上插入数据,导致最终的二叉排序树会退化为链表,从而使得二叉树的查询和插入效率恶化。
平衡二叉树
出现的原因:平衡二叉树(AVL)为了最最求高度平衡,需要通过 平衡处理是的左右子树的高度差必须小于等于1.高度平衡带来的好处时能够更高的搜索效率,其最坏的查找时间复杂度都是O(logN)。但是由于需要维持这份高度平衡,所付出的代价即使当对树种结点进行插入和删除时,需要经过多次旋转实现复衡。着导致AVL的插入和删除效率不高。
每个结点要么时红要么时黑的
根节点时黑的
每个叶节点(叶结点即指树尾端NIL指针或NULL结点)都是黑的
如果一个几点是红的,那么它的两个儿子都是黑的
对于任意结点而言,其到叶节点树尾端NIL指针的每条路径都包含相同数目的黑结点
红黑树
红黑树通过将结点进行红黑着色,使得原本平衡的书机构被稍微打乱,平衡程度降低。红黑树不追求完全平衡,周只要求达到部分平衡。这是一种折中的方案,大大提高了结点删除和插入的效率。C++中STL就常用到红黑树作为底层的数据结构
红黑树 VS 平衡二叉树
除了上面提及的树结构,还有许多应用在数据库,磁盘存储等场景下的树结构。比如B树,B++树等。
树衍生了许多的结构,若将指针域设置为双指针,那么即可形成最常见的二叉树,即每个结点最多有凉饿子树的树结构。二叉树结构根据节点的排列和数量还可进一度划分为完全二叉树,满二叉树,平衡二叉树,红黑树等。
树(Tree)
散列表也叫哈希表,是一种通过键值对直接访问数据的机构。在初中,我们就徐国一种能够将一个x值通过一个函数获得对应的一个y值的操作,叫做映射。散列表的是心啊原理正是映射的原理,通过设定的一个关键字和一个映射函数,就可以直接获得访问数据的地址,是心啊0(1)的数据访问效率。在映射过程中,事先设定的函数就是一个映射表,也可以称作散列函数或者哈希函数
取关键字的某个线性函数值为散列地址。
直接寻址发
通过对数据的分析,发现数据中冲突较少的部分,并构造散列地址。例如同学们的学号,通常同一届学生的学号,其中前面部分差别不太大,所以用后面的部分来构造散列地址。
数字分析发
当无法确定关键字里哪几位的分布相对比较均匀时,可以先求出关键字的平方值,然后按照需要取平方值的中间几位作散列地址。这时因为:计算平方之后的中间几位和关键字中的每一位都相关,所以不同的关键字会以比较高的概率生产不同的散列地址。
平方取中法
使用一个随机函数,取关键字的随机值作为散列地址,这种方式通常用于关键字长度不同的场合。
取随机数法
取关键字被某个不大于散列表的表长n的数m除后所得的余数p为散列地址。这种方式也可以用过其他方法后再使用。该函数对m的选着很重要,一般取素数或者直接用n。
除留取余法
散列表的实现最关键的就是散列函数的定义和选择。一般常用的有一下几种散列函数:
实际上就是当需要存储值时,对key哈希之后,发现指责个地址已经有值了,这时该怎么办?不能放在这个地址,不然之前的映射会被覆盖。这时对计算出来的地址进行一个探测再哈希,比如往后移动一个地址,如果没人占用,就用这个地址。如果超过最大长度,则可以对总长度取余。这里移动的地址时产生冲突时的增列序量
开放地址法(也叫开放寻址法)
再产生冲突之后,使用关键字的其他部分继续计算地址,如果还有冲突,则继续使用其他部分再计算地址。这种方式的缺点时时间增加了
再哈希法
链地址法其实就是对Key通过哈希之后落在同一个地址上的值,做一个链表。其实在很多高级语言的实现当中,也是使用这种方式处理冲突的
链地址法
这总方式时建立一个公共溢出区,当地址存在冲突时,把新的地址放在公共溢出区里。
公共溢出区
确定确定好散列函数之后,通过某个key值的确会得到一个唯一的value地址。但是却会出现一些特殊情况。即通过不同的key值可能会访问到同一个地址,这个现象称之为冲突冲突再发生之后,当再对不同的key值进行操作时会是的造成相同的数据发生覆盖或者丢失,时非常危险的,所以再设计散列表往往还需要采用冲突解决的办法常用处理方式有很多,常用的包括一下几种
散列表(Hash)
左侧数组的每一个成员包括一个指针,指向一个链表的头。每发生一个冲突的数据,就将该数据作为链表的结点连接到链表尾部。这样一来,就可以保证冲突的数据能够区分并顺利访问。
考虑到链表过长造成的问题,还可以使用红黑树替换链表进行冲突数据的处理操作,来提高散列表的查询稳定性‘
堆通常是一个可以被看做一棵树的数组对象。堆的具体实现一般不通过指针域,而是通过构建一个一维数组与二叉树的父节点对应,因此堆总是一棵完全二叉树。
对于任意一个父节点的序号n来说(这里n从o算),它的子节点的序号一定是2n+1,2n+2,因此可以直接用数组类表示一个堆。
堆中某个结点的值总是不大于或小于其父节点的值。将根结点最大的堆叫做最大堆或打根堆,根结点最小的堆叫做最小堆或笑根堆
堆常用来实现优先队列,在面试中经常考的问题都是排序有关,比如堆排序有关,比如堆排序,topK问题等。由于堆的根节点是序列中最大或者最小值,因而可以在建堆以及重建堆的过程中,筛选除数据序列中的极值,从而达到排序或者挑选topK值的目的。
堆(Heap)
图机构一般包括顶点和边,顶点通常用圆圈来表示,边就是这些圆圈之间的连线。边还可以根据顶点之间的关系设置不同的额权重,默认权重相同皆为1.此外根据边的方向性,还可以将图分为有向图和无向图。
还有更多如邻接矩阵,邻接表,逆邻接表,十字链表等
图(Graph)
链表相较于数组,除了数据域,还增加了指针域用于构建链式的存储数据。链表中每一个节点都包含此节点的数据和指向下一节点地址的指针。由于是通过指针进行下一个元素的查找和访问,使得链表的自由度更高。这表现在对节点进行增加和删除是,只需要对上一节点的指针地址尽心修改,二无需变动其它的节点。不过十五皆有两级,指针带泪高自由度的同时,自然会牺牲数据查找的效率和多余空间的使用一般常见的是有头有尾的单链表,对指针域进行反向链接,还可以形成双向链表或者循环链表。
链表和数组对比
链表(Linked LIst)
从链表和数组对比可以看出,链表虽然通过增加指针域提升了自由度,但是却导致数据的查询效率恶化。特别是当链表长度很长的时候,对数据的查询还是得从头依次查询,这样的效率会更低。跳表的产生就是为了解决链表过长的问题,通过增加链表的多级索引来加快原始链表的查询效率。这样的方式可以让查询的时间复杂度从O(n)提升至O(logn)
跳表
常用数据结构
数据结构
从整体上讲,J2EE 是使用 Java 技术开发企业级应用的工业标准,它是 Java 技术不断适应和促进企业级应用过程中的产物。适用于企业级应用的 J2EE,提供一个平台独立的、可移植的、多用户的、安全的和基于标准的企业级平台,从而简化企业应用的开发、管理和部署。J2EE 是一个标准,而不是一个现成的产品。
J2EE是什么
servletServlet是java平台上的CGI技术。Servlet在服务器端运行,动态地生成Web页面。与传统的CGI和许多其他类似CGI的 技术相比,Java Servlet具有更高的效率并更容易使用。对于Servlet,重复的请求不会导致同一程序的多次转载,它是依靠线程的方式来支持并发访问的。JSP(Java server Page)JSP是一种实现普通静态HTML和动态页面输出混合编码的技术。从这一点来看,非常类似Microsoft ASP、PHP等技术。借助形式上的内容和外观表现的分离,Web页面制作的任务可以比较方便地划分给页面设计人员,并方便地通过JSP来合成。在运行时态,JSP将会被首先转换成Servlet,并以Servlet的形态编译运行,因此它的效率和功能与Servlet相比没有差别,一样具有很高的效率。JDBCJDBC(java Database Connectivity,java数据库连接)API是一个标准SQL(Structured QueryLanguage, 结构化查询语言)数据库访问接口,它使数据库开发人员能够用标准java API编写数据库应用程序。JDBC API主要用来连接数据库和直接调用SQL命令执行各种SQL语句。利用JDBC API可以执行一般的SQL语句、动态SQL语句以及带IN和OUT参数的存储过程。Java中的JDBC相当于Microsoft平台中的ODBC(open Database Connectivity)EJBEJB定义了一组可重用的组件:Enterprise Beans。开发人员可以利用这些组件,像搭积木一样建立分布式应用
基本
1. javaEE应用的分层模型大致分为以下几层:(1)Domain Object(领域对象)层:此层由一系列的POJO(Plain Old Java Object,普通的、传统的java对象)组成,这些对象是该系统的Domain Object,往往包含了各自所需实现的业务逻辑方法。(2)DAO(Data Access Object,数据访问对象)层:此层由一系列的DAO组件组成,这些DAO实现了对数据库的创建、查询、更新和删除(CRUD)等原子操作。(3)业务逻辑层:此层由一系列的业务逻辑对象组成,这些业务逻辑对象实现了系统所需要的业务逻辑方法。这些业务逻辑方法可能仅仅用于暴露Domain Object对象所实现的业务逻辑方法,也可能是依赖DAO组件实现的业务逻辑方法。(4)控制器层:此层由一系列控制器组成,这些控制器用于拦截用户请求,并调用业务逻辑组件的业务逻辑方法,处理用户请求,并根据处理结果转发到不同的表现层组件。(5)表现层:此层由一系列的JSP页面,Velocity页面,PDF文档视图组件组成,负责收集用户请求,并显示处理结果。
2. javaEE应用组件:JavaEE构架提供了良好的分离,隔离了各组件之间的代码依赖,javaEE应用大致包括以下几类组件:(1)表现层组件:主要负责收集用户输入数据,或者向客户显示系统状态。最常用的表现层技术是JSP,还可以是Velocity等技术。(2)控制器组件:对于JavaEE的MVC框架而言,框架提供一个前端核心控制器,而核心控制器负责拦截用户请求,并将请求转发给用户实现的控制器组件。而这些用户实现的控制器则负责处理调用业务逻辑方法,处理用户请求。(3)业务逻辑组件:是系统的核心组件,实现系统的业务逻辑。通常一个业务逻辑方法对应一次用户操作。一个业务逻辑方法应该是一个整体,因此要求对业务逻辑方法增加事务性。业务逻辑方法仅仅负责实现业务逻辑,不应该进行数据库访问。因此,业务逻辑组件中不应该出现原始的Hibernate,JDBC等API。(4)DAO组件:Data Access Object,也被称为数据访问对象。这个类型的对象比较缺乏变化,每个DAO组件都提供DomainObject 对象基本的创建、查询、更新和删除等操作,这些操作对应于数据表的CURD等原子操作。当然,如果采用
补充
J2EE主要技术
J2EE
解释:Docker是一个用来装应用的容器,就像杯子可以装水,笔筒可以放笔,书包可以放书,可以把hello word放在Docker中,可以把网站放入Docker中,可以把任何想得到的程序放到Docker中
集装箱
运输方式
存储方式
API接口
标准化
隔离
了解Doker
系统环境不一致
系统好卡,哪个哥们又写是死循环了
双11来了,服务器撑不住
Docker解决的问题
镜像
容器
仓库
走进Docker
https://docs.docker.com/engine/install/centos/
官方文档特别详细
sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
卸载目录
sudo rm -rf /var/lib/dockersudo rm -rf /var/lib/containerd
删除docker资源
官方也有
卸载
Docker安装和卸载
启动Docker
systemctl start docker
显示docker的版本信息
docker version
查看docker的系统信息,包括镜像和容器的数量
docker info
帮助命令
docker 命令 --help
Docke启动关闭
显示文件
docker images -a
只显示id
docker images -aq
搜索镜像名字为mysql
docker search mysql
搜索STARS大于3000的
docker rearch mysql --filter=STARS=3000
下载镜像mysql,默认最新版
docker pull mysql
下载指定版本5.7
doker pull mysql:5.7
删除镜像id为“4f06b49211c0”
docker rmi -f 4f06b49211c0
删除多个镜像
docker rmi -f 4f06b49211c0 3kljlkfj83334
删除镜像容器
docker rmi -f $(docker images -aq)
镜像基本命令
有了镜像才能创建容器,下载centos镜像
docker run -it -p 8080:8080 tomcat
docker run [可选参数] image
新建容器并启动
启动容器centos进入到/bin/bash目录下
docker run -it centos /bin/bash
下载并启动elasticsearch
elasticsearch十分耗内存
docker run -d --name elasticsearch -p 9200:9200 -e \"discovery.type=single-node\" elasticse arch:7.6.2
启动nginx,命名为nginx01,暴露nginx80端口映射到本机的3344端口
docker run -d --name nginx01 -p 3344:80
启动并进入容器
进入名字为nginx01的容器,进入路径/bin/bash
用完就删除
nginx01也可以改为使用image id
docker exec -it nginx01 /bin/bash
进入已启动的容器
docker ps
列出当前正在运行的容器
docker ps -a
列出当前正在运行的容器+带出历史运行过的容器
显示最近一个创建的容器
docker ps -n=1
显示最近创建的容器
只显示历史运行过的容器编号
docker ps -aq
只显示容器的编号
Ctrl + P + Q
退出容器不停止运行
exit
退出容器
删除容器的id为“acd92fc1e7e5”(不能删除正在运行的容器,如要删除)
docker rm acd92fc1e7e5
通过id删除容器
删除所有的容器
docker rm -f $(docker ps -aq)
删除全部容器
docker ps -a -q|xargs docker rm
通过管道符删除所有容器
docker kill 容器id
暂停运行的容器
启动容器
docker start 容器id
重启容器
docker restart 容器id
停止当前正在运行的容器
docker stop 容器id
强制停止当前容器
启动和停止的操作
容器基本命令
docker ps,发现 centtos 停止了
docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
常见的坑 nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
启动tomecat可以使用这个
问题
docker run -d 镜像名
后台启动
查询id为“4c6ba3bbbe60”日志
docker logs -f -t --tail 4c6ba3bbbe60
查看日志
查看id为“2cf36e62ac43”的容器显示最近的10跳
docker logs -tf -tail 10 2cf36e62ac43
显示指定行数的日志
docker run -d centos /bin/sh -c \"while true;do echo kuangshen;sleep 1;done\"
自己编写一段shell脚本
查看容器“2cf36e62ac43”的i进程
docker top 2cf36e62ac43
查看容器中的进程信息
查看容器id为“2cf36e62ac43”的全部信息
docker inspect 2cf36e62ac43
查看容器的全部信息
docker exec -it 2cf36e62ac43 /bin/bash
docker exec -it 2cf36e62ac43 bashShell
进入当前正在运行的容器(进入容器后开启一个新的终端,可以在里面操作(常用))
docker attach 2cf36e62ac43
进入当前正在执行命令的容器(进入容器正在执行的终端,不会启动新的进程)
docker cp 58e290c363f3:/home/test.java /home
docker cp 容器id:容器路径 目的路径
从容器内拷贝文件到主机上
-d 后台运行-p 端口映射-v 卷挂载-e 环境配置--name 容器名字
常用的其他命令
docker search nginx
搜索nginx
docker安装nginx
加上Java限制最小64M,最大512M,防止开发太大,服务器承载不懂
docker run -d --name elasticsearch02 -p 9200:9200 -p 9200:9200 -e \"discovery.type=single-node\" -e ES_JAVA_OPTS=\"-Xms64m -Xmx512m\" elasticse arch:7.6.2
使用elasticsearch
操作命令
Docker具体命令
Docker是一个Client-Servier结构的系统
底层原理
入门Docker
镜像是一个轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某些如软件所需的所有内容,包括代码,运行时,库,环境变量和配置文件
所有的应用,直接打包docker镜像,就可以直接跑起来
从远程仓库下载
朋友拷贝给你
自己制作一个镜像DockerFile
如何得到镜像
镜像是什么
docker commit
提交容器成为一个新的副本
docker commit -a=\"JavaWu\" -m=\"add webapps app\" f87bc6431e53 tomcat02:1.0
docker commit -m=\"提交的描述信息\" -a=\"作者\" 容器id 目标镜像名:[TAG]
提交用户名
启动一个默认的tomcat
启动一个默认的tomcat 是没有webapps应用,镜像的原因,官方的镜像默认webapps下面是没有文件的
自己拷贝进去了基本文件
将我们操作过的容器通过commit提交为一个镜像! 我们以后就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像
实战
Commit镜像
Docker镜像
内网用9000
外网用8088
docker run -d -p 8088:9000 \\--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
Docker可视化界面
我们每次改动nginx配置文件,都需要进入容器内部?十分的麻烦,我要是可以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改? -v 数据卷?
思考?
\"Mounts\": [ { \"Type\": \"bind\
查看是否挂载(在外部查看是否挂载)docker inspect 614049b8739
外部文件使用/home/ceshi内部文件/home 启动centos容器进入/bin/bash页面
docker run -it -v /home/ceshi:/home centos /bin/bash
具体使用
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
docker pull mysql:7.5
获取镜像
运行容器,需要做数据挂载 #安装启动mysql,需要配置密码,这是要注意点!
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
启动mysql
docker run -d -p 3310:3360 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-form mysql01 mysql:5.7这个时候,可以实现两个容器数据同步!
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止
结论
实现多个mysql实现数据共享
Docker实战Mysql
容器数据卷
Dockerfile就是用来构建docker镜像的构建文件!命令脚本!先体验一下!
什么是DockerFile
通过这个脚本可以生成一个镜像,镜像十一层一层的,脚本一个个的命令,每个命令都是一层!
自动挂载
#创建一个dockerfile文件,名字可以随机,建议Dockerfile#文件种的内容 指定(大写) 参数FROM centosVOLUME [\"volume01\
先写脚本
docker build -f /home/docker-test-volume/dockerfile1 -t kuangshen/entos:1.0 .
构建镜像
这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像!假设构建镜像时候美誉挂载卷,要手动挂载, -v 卷名:容器路径!
步骤
初识DockerFile
dockerfile是面向开发的,我们以后要发布项目,就做镜像,就需要编写Dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为企业交付的标准,必要掌握!
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品!
Docker容器:容器就是镜像运行起来提供服务器
Docker File构建过程
FROM
基础镜像,一切从这里开始构建
MAINTAINER
镜像是谁写的,姓名+邮箱
RUN
镜像构建的时候需要运行的命令
ADD
步骤,tomacat镜像,这个tomcat压缩包!添加内容
WORKDIR
镜像的工作目录
VOLUME
挂载的目录
EXPOSE
保留端口配置
CMD
指定这个容器启动的时候要运行的命令
ENTRYPOINT
指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD
当构建一个被继承 DockerFile这个时候就会运行 ONBUILD 的指令,触发指令,
COPY
类似ADD,将我们文件拷贝到镜像中
ENV
构建的时候设置环境变量
DockerFile的指令
Docker Hub中99%镜像都是从这个基础镜像过来的FROM scratch,然后配置需要的软件和配置来进行构建
FROM centosMAINTAINER wuzhiguo<AndyJava@proton.me>ENY MYPATH /usr/localWORKDIR MYPATHRUN yum -y install vimRUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATHCMD echo \"---end---\"CMD /bin/bash
第一步构建Dockerfile文件
docker build -f dockerfile 文件路径 -t 镜像名:[tag]
docker build -f mydockerfile -t mycentos:0.1 .
Successfully built id
Successsfully tagged mycentos:0.1
构建成功
第二步通过这个文件构建镜像
docker run id
第三步测试运行
自己创建一个centos
实战:Tomcat镜像
实战测试
DockerFile
Docker网络原理
IDEA整合Docker
Docker Compose
Docker Swarm
CI\\CDjenkins
Docker具体学习
Docker
高并发
多线程
REST
JVM调优
Git
Ajax
Kibana
elasticsearch
是Docker图形化界面管理工具
portainer
优先
GC算法
递归算法
分治算法
贪心算法
动态规划
枚举算法
算法
理解TCP/IP网络协议
降低用户第一次访问请求被恶意拦截的风险
执行该操作前,请确保已成功配置HTTPS证书
前提条件
https://help.aliyun.com/document_detail/95839.html
HSTS
Typora
中科大 郑烇
计算机网络
华中科技大学 秦磊华
计算机组成原理
哈尔冰工业大学 李治军
操作系统
次要
ctrl+shift+/
ctrl+/
IDEA
软件快捷键
容器技术
完成
外框
基础
已学到31章,后续进阶学习从SpringAlibaba学习在开始
进阶
反向代理
Nginx学习
完成完成
Linux的命令
SpringAlibaba Nacos的学习
学习nacos,会使用反向代理,使用方向代理,快捷部署,使用docker
SpringAlibaba 接下来课程的学习
Mybatis -plus
负载均衡算法
时间线(从上到下,依次学习)
JAVA课程
0 条评论
回复 删除
下一页