极客技术
14 篇文章
随着技术的发展,在欣赏或参与竞技体育项目的时候。
Kafka生产者分区策略 数据可靠性保证
### 分区策略 1. 指明partition的情况下,直接将指明的值作为partition值 2. 没有指明partition值但是有key情况下,将key的hash值与topic的partition数进行取余得到partition值 3. 既没有partition又没有key的情况下,第一次调用产生一个随机整数,然后每次调用会在这个整数上递增,将这个值与topic可用的partition总数取余得到partition值,也就常说的 round-robin(轮询) 算法 ### 数据可靠性保证 1. 两种策略 - 同步半数副本,那么保证数据不丢失需要2n+1个副本 - 同步全部副本,那么保证数据不丢失需要n+1个副本 **kafka采用同步全部副本** 并且优化加入ISR(同步副本)策略,保证如果有一个副本出现不能同步或者同步缓慢而迟迟不能发送ack命令的策略(如果follower长时间未向leader同步数据,则该follower将被踢出ISR,时间阈值由replica.lag.time.max.ms参数设定。) 当Leader发生故障之后,就会从ISR中选区新的leader 2. ISR(同步副本) TODO 3. acks应答机制 参数配置: - acks:`0` producer不等待broker的ack,提供了最低延迟,broker一接受还没写入磁盘就返回,`那么会丢失数据` - acks:`1` producer等待broker的ack,Partition的Leader回落后返回ack,如果在follower同步成功前leader发生故障,`那么会丢失数据`。 - acks:`-1或all` producer等待broker的ack,所有follower同步成功后返回ack - 但是如果follower同步成功但是还没有发送ack的时候 leader坏掉了,这时候重新选举leader,选举成功后会再次发送消息,会造成`消息重复` - 如果ISR副本个数为1的时候 ack设置为all还`可能会丢数据` > 以上的follower都是ISR同步副本中的follower ### ExactlyOnce 精准一次性 1. At least once 至少一次 acks: -1 可以保证数据不丢失,不能保证数据不重复 2. At Most once 至多一次 acks: 0 可以保证数据不重复,不能保证数据不丢失 3. Exactly Once 不重复也不丢失,采用幂等性。0.11之前,采用消费者段进行去重 配置文件设置 `enable.idompotence=true` 即可以开启幂等性 > 生产者在初始化的时候分配一个PID,发往同一Partition的消息会带有Sequence Number。 而且Broker会对<PID,Partition,SeqNumber>做缓存,相同主键提交时候,Broker只会持久化一条。 缺点《生产者,重启后数据还会重复》1
Kafka如何保持数据一致性
## 数据一致性 ### 两个名词 - LEO(Log End Offset) 每个副本的最大offset - HW(High Watermark) 消费者能看到的最大offset,ISR队列中最小的LEO ### 保持一致性得两个场景 - follower故障(长时间未向leader同步数据 时间阈值:replica.lag.time.max.ms): 会被临时踢出ISR,等该follower恢复后,follower会读取本地磁盘上次记录的HW,并将log文件高于HW的地方截取掉,从HW开始向leader进行同步,等follower的LEO大于等于该Partition的HW,追上leader以后,就可以重新加入ISR。 - leader故障: leader发生故障以后会从follower重新选举一个leader,为了保持数据一致性,从剩下follower的log中截掉高于HW的消息,然后从新leader同步数据 **只能保证数据一致性问题,并不能保证数据不丢失或者不重复**
Jenkins 使用原有机器的环境变量
### 查看原有机器环境变量 ``` [root@cvm8184]# echo $PATH /root/.nvm/versions/node/v12.18.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/opt/java/jdk1.8.0_231/bin ``` ### 把服务器的环境变量添加到jenkins 节点管理->设置->环境变量 ![Jenkins 使用原有机器的环境变量](https://qiyue.info/usr/uploads/2020/06/1285336046.png) 这样就可以使用机器已经配置环境变量的软件了,就不用在jenkins中二次安装了
简单理解计算机网络知识记录
网络(计算机网络体系结构模型 - 7层结构) ### 一、OSI与TCP/IP各层的结构与功能,都有哪些协议? 1.1 应用层 > 通过应用进程间的交互来完成特定网络应用 包括域名系统 DNS,HTTP协议 1.2 运输层 - TCP 传输控制协议 面向连接的,可靠的,字节流,效率低的 - UDP 用户数据协议 无连接的,不可靠的,数据报文段,效率高的 1.3 网络层 > 在计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点,确保数据及时传送。 1.4 数据链路层 > 数据链路层 通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。 ### 二、TCP 三次握手和四次挥手 2.1 TCP 三次握手 ![三次握手](https://qiyue.info/usr/uploads/2020/01/1252926793.png) 简单示意图: - 客户端-发送带有SYN标志的数据包-一次握手-服务端 - 服务端-发送带有SYN/ACK标志的数据包-二次握手-客户端 - 客户端-发送带有ACK标志的数据包-三次握手-服务端 2.2 为什么要三次握手 三次握手为了确认自己与对方的发送是正常的。 2.3 TCP 四次挥手 ![四次挥手](https://qiyue.info/usr/uploads/2020/01/3915799633.png) 断开一个TCP连接则需要"四次挥手" - 客户端-发送一个FIN,用来关闭客户端到服务器的数据传送 - 服务器-收到这个FIN,他发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号 - 服务器-关闭与客户端的连接(**半关闭**),发送一个FIN给客户端 - 客户端-发回ACK报文确认,并将确认需要设置为收到序号加1 2.4 为什么要四次挥手 任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。 ### TCP与UDP对比 ![TCP与UDP对比](https://qiyue.info/usr/uploads/2020/01/2026815193.jpg) 总结自 JavaGuide
maven项目编译提示jdk版本低解决办法
在pom文件build节点中添加这个就可以,jdk版本可以指定 ```xml <build> <pluginManagement> <plugins> <!-- 负责编译的maven插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </pluginManagement> </build> ```
利用jdk8 steam() foreach() 对List,Map 进行分组计数
### 情景 需要对List集合里中的实体 某个属性进行分类 并且计数。有点像sql里的group by 并且分组计数 <!--more--> #### 费劲不费心方法 > 比较省心的方式就是循环if ``` java // 我就不放数据了 List list = new List(); int countA = 0; int countB = 0; ... for(i=0;i<list.size();i++){ if("类别A".equals(list.get(i))){ countA++; } if("类别B".equals(list.get(i))){ countB++; } ... } ``` 但是此类方法 会手动创建N个count变量,JAVA我只听过不定参数的用法,没听过不定变量的方法。 感觉有点鸡肋。不如采用以下方法(请自行了解一些lambda表达式基本用法) #### 费心不费劲方法 ``` java // 提取要分类的字段 如上文的 "类别A" 的名称 List<String> fenlei = new ArrayList(); list.forEach(entity -> fenlei.add(entity.getType())); // 利用jdk8对List新增的stream()方法 开始分类并且计数 存到Map类型的exp变量中 Map<String, Long> exp = express.stream().collect(Collectors.groupingBy(Function.identity(),Collectors.counting())); /* Function是jdk8 新增的函数式接口,我了解也不多,同类的还有Consumer 等 */ // exp -> (key:分类名称 value:数量) PS:这里不是lambda表达式 ``` > 其实搜解决办法到实现不过花费我1个小时而已,感觉并不是太费心 > 部分内容参考: [CSDN博客](https://blog.csdn.net/qq_27127145/article/details/83932318"%3Ehttps://blog.csdn.net/qq_27127145/article/details/83932318)
lambda表达式 一些简单应用
> lambda表达式 在很早的时候就看到了,感觉很诱人,但是除了demo,自己也没有真正日常使用过。后来因为论坛中看到有人推荐本书籍。就重新捡起来,也在项目中开始使用。总结一下感觉比较好理解较方便的应用场景。 <!--more--> - For List: 简单筛选List中想要的数据 (比遍历出来if判断要好的多) ```java List <Entity> list=new ArrayList(); List <Entity> more = list.stream().filter(entity -> "2".equals(entity.getType())).collect(Collectors.toList()); ``` - 快速遍历: 也可以使用if等判断逻辑 ```java more.forEach(entity -> { if (entity.getAttach() != null) { System.out.println(entity.getAttach()); } }); ``` > 最后送上一本书,别人推荐的。我也在看 虽然有一部分都看不明白。 《写给大忙人看的JavaSE8》
lombok编译后不生效的情况
昨日研究MyBatis-Plus,采用官网Demo使用的lombok插件和依赖,运行之后发现从前台调用后台的对象出现了一些小小的问题。 ### 事故现场环境 1. IDE:IntelliJ IDEA 2018.2.3 2. 环境及其依赖:Springboot+Thymeleaf+lombok+MyBatis-Plus ### 出现的问题 发现从后台只能调出对象,但是缺调不出对象的属性信息,当初使用IDEA配合Thymeleaf,在html页面是能调出属性的,这次并没有。我的思路就跟Thymeleaf杠上了。结果问题的原因是lombok。 ### 问题分析 ![lombok编译后不生效的情况](https://qiyue.info/usr/uploads/2018/09/935128083.png){width="100%" height="auto"} 冷静下来分析一波,看下报错信息 大概意思是,一个问题发生在模板打印的过程中。 再往后看看,控制台提示我可能没有Getter或者Setter方法。 也就是lombok的@Getter @Setter 没有生效 ### 解决办法 ![lombok编译后不生效的情况](https://qiyue.info/usr/uploads/2018/09/3628783777.png){width="100%" height="auto"} 我这个情况的解决办法是 IDEA设置问题
打开Excel时多打开一个空白文档的解决办法
### 症状 打开Excel(WPS、Office都会出现,当前版本是Office2016)文件都会出现两个窗口,一个是空白的sheet1,另一个是自己的文档。重装无用,换了一台电脑还是这样,我就发现肯定是自己安装的软件问题了。 切记,不是网上说的宏病毒之类的,一点关系没有。 ### 解决办法 出现这个问题的大部分是程序员电脑,粗心大意的程序员,哈哈。 其实这个就是当初安装Mysql的一个加载项,加载项名字叫mysql for excel. #### Office关闭加载项的解决方法: 1. 【文件】 -> 【选项】 -> 【加载项】 2. 【加载项】 -> 【管理】->【选择成COM加载项】 -> 【转到】 ![打开Excel时多打开一个空白文档的解决办法](https://qiyue.info/usr/uploads/2018/08/1945020157.png){width="100%" height="auto"} 3. 【COM加载项】 -> 【取消勾选或者删除MySQL For Excel】 ![打开Excel时多打开一个空白文档的解决办法](https://qiyue.info/usr/uploads/2018/08/4107494463.png){width="100%" height="auto"} #### WPS关闭加载项的解决方法: 【工具】 -> 【COM加载项】 -> 【取消勾选或者删除MySQL For Excel】
JAVA批量导入大文本数据(1G+)
这个不是造轮子,只是整理轮子,我在搜索引擎里,遇到的思路都是第一种思路(至少按照标题那个关键词搜索是这样的)所以我想发出来。 - 一是如果遇到大神帮忙发现了方案一的问题与弊病,那就更好啦。 - 二是让大家不会像我一样,只有一个思路。 这里感谢我的玉坤同学,提供给我第二种思路,还替我研究半天问题。 > 情景:最近工作中,需要处理1G+的文本文件简单处理后导入到数据库。 ### 通用部分 方案都采用IO流中的Buffered系列,读取文件时候,采用了BufferedReader的输入流缓存。(搬来的,网上借鉴的) ```java // 文件路径 File file = new File("F:\demo\demo.txt"); // 输入流 BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file)) // 30M的缓存 BufferedReader reader = new BufferedReader(new InputStreamReader(fis,"utf-8"),30*1024*1024); ``` **一定记得flash()或者close(),否则会出现意想不到的小问题,我没有关闭输出流,就出现文件少写的现象。** ### 方案一(排除) 用纯正的JDBC语句,选用带缓存性能比较好的`prepareStatement`,但是从文本中插入数据库到1W3行左右就出现了问题: `java.net.SocketException: No buffer space available (maximum connections reached?)`:与`Communications link failure`的错误 我上网搜索良久,网上给的建议是增加数据库连接数和超时时间,我采用了并不能彻底解决问题(不会在1W行死掉了,但是也没多写多少文件) > 如果有解决办法,请慷慨相授,我会代替广大网友谢谢您! ### 方案二(目前采用) > 并且猜测Navicat的'导入向导'也是利用此方法 利用Mysql的load data infile方法: ``` load data infile '文件全路径' replace into table 表名 character set utf8 fields terminated by '分割串' enclosed by '"' lines terminated by '\r\n' (字段列); ``` 说实话,网上也有不少介绍Load data infile的。如果您能看懂这个,那这个绝对比网上找的长篇大论上手快。反正那些我看的是脑壳疼。
09
文章聚合
Hello,August
Hello,May
Hello,July