Other

Nacos源码系列—关于服务注册的那些事

点赞再看,养成习惯,微信搜索【牧小农】关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友。 项目源码地址:公众号回复 nacos,即可免费获取源码 简介 首先我们在看Nacos源码之前,要先想想为什么我们要读源码?是为了装杯?还是为了在心仪的女神面前给她娓娓道来展示自己的代码功底?当然不全是! 这都不是我们读源码的最终目的。作为一名技术人,上面的都是浮云,真正激励我们的应该是能够提升我们技术功底和整体技术大局观。此乃大道也!闲言少叙,接下来我们就来看一看,看源码究竟有什么好处 提升技术功底: 当我们去看源码的时候,能够学习源码里面优秀的设计思想,还含有设计模式和并发编程技术,解决问题的思路,能够知其所以然 新技术学习能力: 当我们看多了源码,对于一个新技术或者框架的掌握速度会有大幅度提升,能根据经验或官网资料快速掌握底层的实现,技术更新迭代也可以更快的入手 快速解决问题能力: 遇到问题,尤其是框架源码的问题,能够更快速的定位 面试获取更高成功率: 现在出去面试,一般中高级一点的,都会问到框架源码级别的实现,如果能够说出来,可以提升面试的成功率和薪资待遇,源码面试是区别程序员水平另一面镜子 认识更多圈子: 多活跃开源社区,熟读源码后多思考,发现问题或需求主动参与开源技术研发,与圈内大牛成为为朋友 阅读源码的方法 搭建入门demo: 我们可以先看一下官网提供的文档,搭建Demo,快速掌握框架的基本使用 看核心代码: 对于初次看源码的同学,不要太过于关注源码的细枝末节,先把主要核心流程梳理出来,找到其入口,分析静态代码,如果遇到问题,可以进行断点调试。 绘图和笔记: 梳理好核心功能后,可以用流程图记录下来,好记性不如烂笔头,同时对关键的源码部分可以进行备注,分析参数的变化。同时要善于用Debug,来观看源码的执行过程 复习总结: 当我们把框架的所有功能点的源码都分析完成后,回到主流程在梳理一遍,最后在自己脑袋中形成一个闭环,这样源码的核心内容和主流程就基本上理解了。 Nacos核心功能点 服务注册: Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如IP地址,端口等信息。Nacos Server接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中。 服务心跳: 在服务注册后,Nacos Client会维护一个定时心跳来支持通知Nacos Server,说明服务一直处于可用状态,防止被剔除。默认5s发送一次心跳。 服务健康检查: Nacos Server会开启一个定时任务用来检查注册服务实例的健康状况,对于超过15s没有收到客户端心跳的实例会将它的healthy属性设置为false(客户端服务发现时不会发现)。如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册) 服务发现: 服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面注册的服务清单,并且缓存在Nacos Client本地,同时在Nacos Client本地开启一个定时任务定时拉取服务端最新的注册表信息更新到本地缓存 服务同步: Nacos Server集群之间会互相同步服务实例,用来保证服务信息的一致性 Nacos源码下载 首先我们需要将Nacos的源码下载下来,下载地址:https://github.com/alibaba/nacos 我们将源码下下来以后,导入到idea中 proto编译 当我们导入成功以后,会出现程序包com.alibaba.nacos.consistency.entity不存在的错误提示,这是因为Nacos底层的数据通信会基于protobuf对数据做序列化和反序列化,需要先将proto文件编译为对应的Java代码。 最简单的 不安装任何的东西 idea2021.2已经捆绑安装了这个。 可以通过mvn copmpile来在target自动生成他们。 Nacos缺少Istio依赖问题解决 我们只需要在文件根目录下执行以下命令即可: mvn clean package -Dmaven.test.skip=true -Dcheckstyle.skip=true 做完以上两步,我们就可以启动Nacos的了

MySQL数据库03

自增特性 create table t1( id int primary key auto_increment, name varchar(32) ); insert into t1(name) values('jason'),('kevin'),('tony'); insert into t1(name) values('oscar'); # id=4 delete from t1 where id=4; insert into t1(name) values('oscar'); # id=5 自增不会随着数据的删除而回退!!! delete from t1; # 删除数据但无法重置主键 insert into t1(name) values('jason'),('kevin'),('tony'); truncate t1; # 删除数据并重置主键值 insert into t1(name) values('jason'),('kevin'),('tony'); 外键引入 ''' 创建一张员工表 id name age dep_name dep_desc 缺陷: 1.表的重点不清晰(可以忽略) 既可以说是员工表也可以说是部门表 2.表中某些字段对应的数据一直在重复(可以忽略) 浪费存储空间 3.表的扩展性极差 牵一发而动全身(不能忽略) 耦合度太高 不利于维护 解决: 将一张表一分为二 员工表 部门表 id name age id dep_name dep_desc ''' ''' 拆分之后,员工与部门之间没有了绑定关系; 在员工表中添加一个部门编号字段与部门表中的主键字段对应; 这个字段就是外键,因此引入了外键的概念 ''' 社会中存储需要可以构建成表的数据, 它们形成的表,往往之间存储某种或某些社会关系,mysql数据库建立表结构就是社会中产生的各种数据,,分门别类管理但mysql建立的(代码层次的)表之间,,同样需要处理表与表之间的关系,形成了 多对一 、多对多 、一对一的关系。

3.3 Linux绝对路径和相对路径详解

在 Linux 中,简单的理解一个文件的路径,指的就是该文件存放的位置,例如,在《Linux文件系统的层次结构》中提到的 /home/cat 就表示的是 cat 文件所存放的位置。只要我们告诉 Linux 系统某个文件存放的准确位置,那么它就可以找到这个文件。 指明一个文件存放的位置,有 2 种方法,分别是使用绝对路径和相对路径。 我们知道,Linux 系统中所有的文件(目录)都被组织成以根目录“/”开始的倒置的树状结构,如图 1 所示。 图 1 Linux系统文件组织结构示意图 绝对路径一定是由根目录 / 开始写起。例如,使用绝对路径的表示方式指明 bin 文件所在的位置,该路径应写为 /usr/bin,测试代码如下: [root@localhost ~]# bin bash: bin: command not found <-- 没有找到 [root@localhost ~]# /usr/bin bash: /usr/bin: is a directory <-- 是一个文件 可以看到,如果仅传递给 Linux 系统一个文件名,它无法找到指定文件;而当将 bin 文件的绝对路径传递 Linux 系统时,它就可以成功找到。 和绝对路径不同,相对路径不是从根目录 / 开始写起,而是从当前所在的工作目录开始写起。使用相对路径表明某文件的存储位置时,经常会用到前面讲到的 2 个特殊目录,即当前目录(用 . 表示)和父目录(用 .. 表示)。 举个例子,当我们使用 root 身份登录 Linux 系统时,当前工作目录默认为 /root,如果此时需要将当前工作目录调整到 root 的子目录 Desktop 中,当然可以使用绝对路径,示例代码如下:

PE头-关于内存地址反推和unpackme#1的应用

在unpackme#1的破解中,涉及到修改PE文件。 其步骤是现在在text节的空白处填写代码,并在PE文件中修改执行OEP。  问题一 ee f8 01是怎么来的 je short 00401083是e9 96 01修改为ee f8 01的思路的关键是考虑到原有是经过加密,直接修改自己写的地址并非加密的,执行时是会出现错误,所以要针对的异或加密。  问题二 如何确定要修改的地址 内存中地址要反推到PE文件的值。 起始值:确定起始内存地址 偏差值:当前地址减去起始地址  节:确定节的位置,根据PE文件中节VA的定义判断 偏移值:节-VA 具体值:再根据PointerToRawData+偏移值 如果存在重定位等问题时,则是根据具体的起始内存开始计算,只不过计算的是相对值,

数据库---mysql外键和分组

自增特性 案例: create table t1( id int primary key auto_increment, name varchar(32) ); insert into t1(name) values('jason'),('kevin'),('tony'); delete from t1 where id=2; insert into t1(name) values('oscar'); delete from t1 where id=4; insert into t1(name) values('oscar'); select * from t1; # 结果 +----+-------+ | id | name | +----+-------+ | 1 | jason | | 3 | tony | | 5 | oscar | +----+-------+ 结论:自增不会随着数据的删除而回退;delete删除数据但无法重置主键,truncate删除数据重置主键。 外键 外键是某个表中的一列,它包含在另一个表的主键中。外键字段就是用来记录表与表之间数据的关系。

3.4 Linux文件(目录)命名规则

介绍完 Linux 系统中目录结构之后,读者一定想知道如何为文件或目录命名。 我们知道,在 Linux 系统中,一切都是文件,既然是文件,就必须要有文件名。同其他系统相比,Linux 操作系统对文件或目录命名的要求相对比较宽松。 Linux 系统中,文件和目录的命名规则如下: 除了字符“/”之外,所有的字符都可以使用,但是要注意,在目录名或文件名中,使用某些特殊字符并不是明智之举。例如,在命名时应避免使用 <、>、?、* 和非打印字符等。如果一个文件名中包含了特殊字符,例如空格,那么在访问这个文件时就需要使用引号将文件名括起来。 目录名或文件名的长度不能超过 255 个字符。 目录名或文件名是区分大小写的。如 DOG、dog、Dog 和 DOg ,是互不相同的目录名或文件名,但使用字符大小写来区分不同的文件或目录,也是不明智的。 与 Windows 操作系统不同,文件的扩展名对 Linux 操作系统没有特殊的含义,换句话说,Linux 系统并不以文件的扩展名开分区文件类型。例如,dog.exe 只是一个文件,其扩展名 .exe 并不代表此文件就一定是可执行文件。 需要注意的是,在 Linux 系统中,硬件设备也是文件,也有各自的文件名称。Linux 系统内核中的 udev 设备管理器会自动对硬件设备的名称进行规范,目的是让用户通过设备文件的名称,就可以大致猜测处设备的属性以及相关信息。 udev 设备管理器会一直以进程的形式运行,并侦听系统内核发出的信号来管理位于 /dev 目录下的设备文件。 表 1 罗列出了Linux 系统中常见硬件设备的文件名。 硬件设备 文件名称 IDE设备 /dev/hd[a-d],现在的 IDE设备已经很少见了,因此一般的硬盘设备会以 /dev/sd 开头。 SCSI/SATA/U盘 /dev/sd[a-p],一台主机可以有多块硬盘,因此系统采用 a~p 代表 16 块不同的硬盘。 软驱 /dev/fd[0-1] 打印机 /dev/lp[0-15] 光驱 /dev/cdrom 鼠标 /dev/mouse 磁带机 /dev/st0 或 /dev/ht0

3.5 Linux命令行下如何识别文件类型?

对于第一次使用 Linux 命令行的用户,可能真的搞不清楚哪个是文件,哪个是目录,究其原因是很难直接通过名字看出来目录和文件的区别。 虽然从名称上不容易分辨,但是可以从颜色上进行区分。一般情况下,Linux 用蓝色代表目录,其他颜色则表示是文件。例如: 图 1 /root 目录下的文件和目录 注意,本节多处会使用 pwd(显示当前工作所在的目录)和 ls(列出当前目录中包含的所有文件和子目录)命令,读者只需了解它们的功能即可,本章后续会对它们做详细介绍。 和 Linux 不同,Windows 下带有<DIR> 标记的行或使用中括号“[]”括起来的名称就是目录,其他的则是文件(如图 2 所示)。 图 2 Windows命令行区分文件和目录(文件夹) 不仅如此,Linux 中还可以用不同的颜色来区分不同种类的文件,例如绿色代表可执行文件、红色代表压缩文件、浅绿色代表链接文件、白色代表其他文件、黄色代表设备文件等。 但是,不同颜色所代表的文件类型不一定是这样,更准确的对应方式还取决于配置文件 /etc/DIR_COLORS 中的规定。因此,如果想详细了解不同文件类型所对应的颜色,可以使用 man 命令,例如: [root@localhost ~]# man dir_colors 注意,有些 Linux 发行版单独使用 ls 命令,无法显示出带有不同颜色的文件和目录,此时就需要使用 ls --color=auto 命令,明确令其使用颜色来区分文件类型。 在此基础上,如果不想每次使用 ls 命令时,都显式附带 --color=auto,可以执行如下命令: [root@localhost ~]# alias ls = 'ls --color=auto' 通过给 ls --color==auto 这个整体设置一个别名 ls,这样当后续使用 ls 命令时,就等同于执行 ls --color=auto 命令。 同时,如果想使这个设置永远生效,还需要将其添加到 /etc/bashrc 或 /home//.

3.6 Linux命令基本格式

本节开始,我们不会再见到图形界面了,因为对服务器来讲,图形界面会占用更多的系统资源,而且会安装更多的服务、开放更多的端口,这对服务器的稳定性和安全性都有负面影响。其实,服务器是一个连显示器都没有的家伙,要图形界面干什么? 说到这里,有很多人会很崩溃。笔者就经常听到抱怨 Linux 是落后于时代的老古董,就像笔者的白头发一样!但是,大家要理解,对服务器来讲,稳定性、可靠性、安全性才是最主要的。而简单易用不是服务器需要考虑的事情,所以学习 Linux,这些枯燥的命令是必须学习和记忆的内容。 命令提示符 登录系统后,第一眼看到的内容是: [root@localhost ~]# 这就是 Linux 系统的命令提示符。那么,这个提示符的含义是什么呢? []:这是提示符的分隔符号,没有特殊含义。 root:显示的是当前的登录用户,笔者现在使用的是 root 用户登录。 @:分隔符号,没有特殊含义。 localhost:当前系统的简写主机名(完整主机名是 localhost.localdomain)。 ~:代表用户当前所在的目录,此例中用户当前所在的目录是家目录。 #:命令提示符,Linux 用这个符号标识登录的用户权限等级。如果是超级用户,提示符就是 #;如果是普通用户,提示符就是 $。 家目录(又称主目录)是什么? Linux 系统是纯字符界面,用户登录后,要有一个初始登录的位置,这个初始登录位置就称为用户的家: 超级用户的家目录:/root。 普通用户的家目录:/home/用户名。 用户在自己的家目录中拥有完整权限,所以我们也建议操作实验可以放在家目录中进行。我们切换一下用户所在目录,看看有什么效果。 [root@localhost ~]# cd /usr/local [root@localhost local]# 仔细看,如果切换用户所在目录,那么命令提示符中的会变成用户当前所在目录的最后一个目录(不显示完整的所在目录 /usr/ local,只显示最后一个目录 local)。 命令的基本格式 接下来看看 Linux 命令的基本格式: [root@localhost ~]# 命令[选项][参数] 命令格式中的 [] 代表可选项,也就是有些命令可以不写选项或参数,也能执行。那么,我们就用 Linux 中最常见的 ls 命令来解释一下命令的格式(有关 ls 命令的具体用法,后续章节会详细介绍)。如果按照命令的分类,那么 ls 命令应该属于目录操作命令。 [root@localhost ~]# ls anaconda-ks.cfg install.log install.

【基础算法】next_permutation的手动实现

420. 火星人 #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int N = 1e4 + 10; int n, m; int w[N]; int main() { scanf(%d%d, &n, &m); for(int i = 1; i <= n; i ++ ) scanf(%d, &w[i]); while(m -- ) { int k = n; while(w[k - 1] > w[k]) k -- ; int t = k; while(w[t + 1] > w[k - 1]) t ++ ; swap(w[k - 1], w[t]); reverse(w + k, w + n + 1); } for(int i = 1; i <= n; i ++ ) printf(%d , w[i]); return 0; } 作者:Once.

TCP网络编程

1.前置基础知识: 一、网络编程中的两个主要问题:1.如何准确定位网络上的一台或多台主机,定位主机上的特定应用2.找到主机后如何进行高效的传输二、网络编程中的两个要素:1.提供IP和端口号解决主机寻找问题2.提供网络协议(如TCP/IP)实现高效传输三、通信要素一:IP和端口号1.IP:唯一标识Internet上的计算机2.在Java中使用InetAddress代替IP3.IP的分类:IPv4和IPv6 万维网和局域网4.域名:www.baidu.com www.mi.com5.本地回路地址:127.0.0.1 ,对应localhost6.实例化InetAddress的两个方法:getByName(String host),getLocalHost() 两个常用方法:getHostName()/getHostAddress()7.端口号:正在计算机上运行的进程要求:不同进程的端口号不同范围:0——655358.端口号与IP构成一个网络构接字代码的有关测试: 1 public class InetAddressTest { 2 public static void main(String[] args) { 3 try { 4 InetAddress inet1 = InetAddress.getByName(192.168.10.14); 5 System.out.println(inet1); 6 //获取域名的IP地址 7 InetAddress inet2 = InetAddress.getByName(www.baidu.com); 8 System.out.println(inet2); 9 //获取本机的IP地址 10 InetAddress inet3 = InetAddress.getLocalHost(); 11 System.out.println(inet3); 12 System.out.println(inet2.getHostName()); 13 System.out.println(inet2.getHostAddress()); 14 } catch (UnknownHostException e) { 15 throw new RuntimeException(e); 16 } 17 } 18 }   2.