自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

李昊轩的博客

Done is better than perfect.

  • 博客(374)
  • 资源 (4)
  • 论坛 (1)
  • 收藏
  • 关注

原创 越过时针回拨的坑, 解决重启导致的雪花算法id重复问题, 文末附送踩坑总结大礼包!

在上一篇文章中通过PowerMockito来模拟时钟回拨, 验证改进版雪花算法是否起效我们了解了什么是时针回拨, 怎样去解决它, 但是像雪花算法这种高性能的id生成器, 比较娇贵, 比如在我将这个算法投入到生产之前, 发现这个算法在重启之后再压测的时候, 会出现大量重复的id, 当时就猜测可能算法本身有一个记载状态的属性, 去读源码, 果然找到了, 这个属性叫epoch.Id重复发生原因:epoch对应该算法第一次初始化传入的时间, 也就是算法的生日~~因为这个epoch在每次启动的时候默认传入

2021-07-14 17:35:11 114

原创 已经用k8s来部署运维各个微服务的组件,是否可以不用整套微服务?

https://www.zhihu.com/question/430048535/answer/1582533126可以,但要看情况。以主流的SpringCloud为例,其提供的能力与Kubernetes既有重合也有互补,我们举几个例子逐一分析微服务各个核心组件。微服务网关网关几乎不涉及业务部分,各种实现也非常多,选哪个看业务契合度了。但Spring Cloud Gateway不能作为Kubernetes Ingress Controller,如果用不兼容Ingress的框架作为网关层,可能会损失一

2021-05-06 13:37:36 28188 10

原创 从RedisTemplate, StringRedisTemplate 的序列化异同引发的思考

长话短说:StringRedisTemplate, RedisTemplate 都是redis在Spring中的封装的模板工具类StringRedisTemplate 从名字看, 是用来存取String的RedisTemplate 从名字上看, 是什么都能干, 包含上面的两种实现都会将key使用对应的不同的序列化实现类实现因为是不用的序列化实现类, 所以出现了一个现象:比如在StringRedisTemplate中 将 a --> value 存入但是在 RedisTemplate 中

2021-04-27 17:52:23 3446 6

原创 通过PowerMockito来模拟时钟回拨, 验证改进版雪花算法是否起效

改进版雪花算法详见上篇传送门简单说明: 通过PowerMockito来mock雪花算法中获取时间的算法, 从而实现伪造时间覆盖.测试类import org.junit.Assert;import org.junit.Before;import org.junit.Test;import org.junit.runner.RunWith;import org.powermock.api.mockito.PowerMockito;import org.powermock.core.classlo

2021-04-21 17:56:15 2148 3

原创 短小精悍! 2分钟 5步 咔咔搞定kubenetes新版(v1.20+)集群安装

首先得有个集群, 我这里用两个虚拟机演示, 这里就不讨论如何安装虚拟机了, 虚拟机的网络都会安装吧, 相信点进来的大家都会搞定应有环境的.第一步最不起眼, 但是影响最大的一步! 关闭selinux 和 swap, 注意是永久关闭, 如果使用命令关闭的话, 在k8s集群重启的话会导致启动失败, 而且相关报错信息会很有误导性(swap 会有提示, selinux的报错很迷), 防火墙也别忘了开启对应端口, 不懂的同学并且不是生产环境的话, 直接关闭就好.第二步安装docker, 自启动有几台机器就在几

2021-03-25 15:25:09 7007 2

原创 硬核讲解JDK1.8的ConcurrentHashMap为何放弃分段锁改用CAS + synchronized
原力计划

jdk1.7分段锁的实现和hashmap一样,在jdk1.7中ConcurrentHashMap的底层数据结构是数组加链表。和hashmap不同的是ConcurrentHashMap中存放的数据是一段段的,即由多个Segment(段)组成的。每个Segment中都有着类似于数组加链表的结构。关于SegmentConcurrentHashMap有3个参数:initialCapacity:初...

2020-04-15 04:21:03 33226 12

原创 使用CGLib动态代理jdbc原生类来实现应用层无感知的proxy层面的SaaS分库支持

本文紧接上一篇独家首发! java助力mycat实现动态添加数据源, 实现SaaS新增租户秒登独立数据库使用了动态代理来代理了jdbc的PreparedStatement对象,是SaaS应用层实现的具体对接:这个纯属我个人考虑开发效率搞的骚操作, 因为动态代理肯定是没有一个一个重写这种静态编译效率高, 希望给大家多一种解决思路~~public class CGLIBProxyPreparedStatement { static String s = "executeupdate,execu

2021-07-14 18:07:14 109

原创 nginx配置静态资源缓存, 同时配合k8s的SVC(core dns)实现负载均衡

最近发现以上线的tomcat web服务静态资源加载比较慢, 而且每次都会重新从服务端拉取, 这里肯定是有缺陷并且需要改进的. 然后决定使用nginx解决, 通过配置静态资源缓存实现动静分离, 同时发现k8s的dns解析果然简单粗暴, 非常实用, 直接无侵入式的实现了nginx的负载均衡(通过在server块的地址里直接配置SVC), 搞定!后面我也会单独写一篇k8s的coredns/kubedns的工作原理, 和大家一起探讨.下面是详细的配置文件Nginx.conf# 静态资源加速, 动静分离

2021-06-17 14:17:03 425 1

原创 使用Jenkins实现重构项目并部署项目到阿里k8s环境运行

第一步比如我有一个项目A, 并且jenkins里配置的构建分支名称为 --> branchA所以在构建前, 需要将最新的master分支merge到branchA分支, 保证gctest拥有全部最新的代码变更.第二步以这个A项目为例,进入到Jenkins主页面点击我们的namespace 这个是我们的safefood集群的的namespase点击A项目进入到A项目管理页面后, 点击BuildNow下方会有个类似的进度条, 表示该系统正在构建, 可以点击进去, 查看详细构建lo

2021-06-09 18:10:56 179

原创 Java中String与File的互相转换

今天有这个需求, 记了下来, 算是搬运, 感谢!字符串转文件/** * 将字符串写入指定文件(当指定的父路径中文件夹不存在时,会最大限度去创建,以保证保存成功!) * * @param res 原字符串 * @param filePath 文件路径 * @return 成功标记 */ public static boolean string2Fi

2021-06-08 18:23:36 148

原创 gradle和maven对比

本文是我逛知乎的时候看到的的大佬发言, 转载于此.首先gradle和maven根本就不是同一种类的东西,gradle是构建工具,为了构建,带有依赖缓存功能(不是包管理功能)maven是依赖包管理工具,通过插件带有一定的构建能力。看清楚他们的侧重点没有,gradle可以完成非常复杂的构建,你用它的dsl可以玩出各种花样来,所以它特别适合android这种重客户端,组件越多越复杂的应用(本质就是巨石应用)它越得心应手,反之如果你没有特别复杂的打包要求,那你就是在用牛刀杀鸡了。gradle没有依赖包

2021-06-07 18:11:10 46

原创 独家首发! java助力mycat实现动态添加数据源, 实现SaaS新增租户秒登独立数据库

这里先简单介绍一下背景, 防止看官迷糊首先手上有一个项目要实现分库, 技术选型为mycatA(运维系统), B(SaaS系统)目标效果(时间顺序 -> 1 -> 2 -> 3 -> 4):管理员在A系统新增租户时新建并初始化新租户的数据库java程序自动在mycat的配置中添加新增租户的配置向mycat发送reload命令, 失败自动触发重试机制.新租户直接在B系统登录成功.由于我怀疑File这个类的在mac和linux的native方法有略微区别, 导致

2021-06-03 18:09:54 3674

原创 Mycat 1.6.6 容器化部署

最近有需求要把mycat部署到k8s, 还是自己打包镜像靠谱, 直接干货走起:本文mycat安装包 以及dockerfile下载dockerfileFROM java:8-jre # 随便一个基础镜像 这里用java8演示USER rootCOPY Mycat-server-1.6.6.1-release-20180908155252-linux.tar.gz /RUN tar -zxf /Mycat-server-1.6.6.1-release-20180908155252-linux.tar

2021-06-01 15:21:59 172

原创 Stream A method annotated with @StreamListener having a return type should also have an outbound tar

说明消费者注解的方法存在返回值, 需要特殊处理两种方法:void在该方法上使用@SendTo 发送到其他队列

2021-05-19 17:05:37 551

原创 什么是函数的side effects, 如何通俗的理解它?

Side effect就是“副作用”(侧面影响),通常是对于一个函数而言的,说一个函数“有副作用”或者“没有副作用”。如果一个函数修改了自己范围之外的资源,那就叫做有副作用,反之,就是没有副作用。总结一下, 有副作用(side effects)的函数会做(不限于)这些事情:修改全局变量修改输入参数所引用的对象做输入输出操作调用其他有副作用的函数...

2021-05-07 09:28:31 22221 1

原创 通过incr命令也可以实现redis分布式锁

/** * 从redis获取分布式锁 * * @return workerId */ public static Long lockTest() throws InterruptedException { // 尝试获取锁 原理: incr命令只有在第一次进入空节点时会返回1. Long res = RedisClientContext.getInstance().getStringRedisTemplate().opsFo.

2021-04-26 15:58:11 1736 3

原创 什么是指针回拨? 优化snowflake指针回拨的缺陷(不引入任何第三方中间件(redis, zk))

首先简单了解下, 什么是指针回拨?很多普遍的唯一ID算法, 例如雪花算法, 他们算法是根据本机的机器码, 还有本机时间得出的, 他们对本机的时间是强依赖的.服务器的硬件时钟的时间存在误差, 需要例如ntp服务来进行的自我校准,在回拨的期间, 这段时间是已经被ID生成算法使用过的, 也就变成了二手时间, 这个二手时间, 可能导致了我们再次计算ID时, 我们的参数因子都是相同的, 最终导致了生成完全重复的ID.那么怎么避免呢?等待这个二手时间过去(因为回拨时间大概率不会太长)侦测二手时间段,

2021-04-19 15:55:26 4671 3

原创 简单总结下git fetch 和 pull的区别

研究了好久, 简单总结一下:把当前分支比作一个软件, 那么 git fetch相当于检测版本更新, 并不会真正的去更新, 也没有改变本地分支的代码.git fetch只会将本地库所关联的远程库的commit id更新至最新git pull = fetch(检测更新) + pull(执行更新)...

2021-04-19 14:29:10 813 3

原创 DNS 是怎样同时使用TCP, UDP的

DNS同时占用UDP和TCP端口53, 比较奇怪DNS在进行区域传输的时候使用TCP协议,其它时候则使用UDP协议, DNS的规范规定了2种类型的DNS服务器,一个叫主DNS服务器,一个叫辅助DNS服务器。在一个区中主DNS服务器从自己本机的数据文件中读取该区的DNS数据信息,而辅助DNS服务器则从区的主DNS服务器中读取该区的DNS数据信息。当一个辅助DNS服务器启动时,它需要与主DNS服务器通信,并加载数据信息,这就叫做区传送(zone transfer)。为什么既使用TCP又使用UDP?TC

2021-04-09 15:36:14 1005 2

原创 k8s 一图看懂StorageClass pv pvc关系

集群管理员预先创建存储类(StorageClass);用户创建使用存储类的持久化存储声明(PVC:PersistentVolumeClaim);存储持久化声明通知系统,它需要一个持久化存储(PV: PersistentVolume);系统读取存储类的信息;系统基于存储类的信息,在后台自动创建PVC需要的PV;用户创建一个使用PVC的Pod;Pod中的应用通过PVC进行数据的持久化;而PVC使用PV进行数据的最终持久化处理。...

2021-04-09 11:30:34 788 1

原创 k8s服务发现 headless svc和 普通svc 区别

首先我们把 svc 本身看做为首, svc的endpoints对应的pods看作是尾普通 svc我们可以看作是有头svc, 表示svc本身也有一个地址(cluster ip), dns查询时只会返回Service的地址, 具体client访问的是哪个Real Server,是由iptables来决定的headless svcheadless 无头, 无头表示这个svc的负载均衡是没有clusterip的, dns查询会如实的返回2个真实的endpointheadless优点第一种:自

2021-04-07 17:42:55 846 1

原创 mysql 主从, 多主多从, cluster区别

主从 读写分离cluster集群多节点同时读写主从写压力扩展就是多套主从,相对麻烦,但是架构灵活,性能好多点读写cluster模式都避不开一个写性能问题,写一个节点需要同步到所有节点才能算一个事务, 比较麻烦...

2021-04-07 16:38:18 328

原创 k8s port nodeport targetport containerport 区别

portpod 暴露出来的端口 相对于k8s内部的ipnodeportpod 上层svc对外暴露出的端口, 相对与外部物理机targetportport内部对接容器的端口, targetPort是pod上的端口,从port/nodePort上来的数据,经过kube-proxy流入到后端pod的targetPort上,最后进入容器。containerport镜像暴露的地址, 在pod内部的docker(容器实现)暴露的端口...

2021-04-02 12:03:42 384

原创 kubernetes安装Jenkins 挂载NAS 并汉化

首先我们要建立一个namespacekubectl create namespace kube-opspvc pv关于pv 我用的是阿里的k8s nas 所以点点点就好, 这里提供了yml创建方式, 一样的, 注意pvc的名字要和deployment声明的一致apiVersion: v1kind: PersistentVolumemetadata: name: opspvspec: capacity: storage: 20Gi accessModes: - Read

2021-04-02 11:10:20 483 1

原创 k8s dashboard token过期时间太短的解决方案

点击红框位置, 编辑yaml配置文件args这里增加一行 - '--token-ttl=43200'

2021-03-30 16:13:31 1829 2

原创 K8s 安装可视化dashboard, 并授权登录,(附跳过chrome https证书验证)

不多说, 直接apply 下面文件kubectl apply -f dashboard.yaml# Copyright 2017 The Kubernetes Authors.## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of t

2021-03-30 12:04:28 374 2

原创 k8s彻底删除指定pod

kubectl删除pod的指令kubectl delete pod <podname> -n <namespace>但是很多情况下, 上面的命令和k8s 的容灾机制冲突了, 也就是说, k8s会误认为这个pod异常挂掉了, 然后立即启动个新的pod, 从而导致了春风吹又生的情况.既然理解了问题根源, 那我们只需要先撤销掉该pod的容灾机制, 比如删除他的deployment机制.查看所有deployment 信息kubectl get deployment -n <

2021-03-29 17:00:24 739

原创 如何永久关闭selinux

getenforce 查看状态setenforce 0 关闭内存中的配置(重启失效)vi /etc/selinux/config设置 SELINUX=permissivereboot 搞定

2021-03-24 17:42:48 320

原创 kubernetes系列之secret 与 configMap

configmap和secret是两种特殊的存储卷,它们不是给pod提供存储空间用的,而是给管理员或者用户提供了从外部向pod内部注入信息的方式.configmap:把配置文件放在配置中心上,然后多个pod读取配置中心的配置文件,不过,configmap中的配置信息都是明文的,所以不安全;secret:功能和configmap一样,只不过配置中心存储的配置文件不是明文的.configmap和secret也是专属于某个名称空间的.# 用命令行创建configmapkubectl create conf

2021-03-15 15:59:34 321

原创 Kubernetes系列之存储详解 emptyDir hostPath nfs pv/pvc 动态卷供应

Volume类型volume是kubernetes Pod中多个容器访问的共享目录。volume被定义在pod上,被这个pod的多个容器挂载到相同或不同的路径下。volume的生命周期与pod的生命周期相同,pod内的容器停止和重启时一般不会影响volume中的数据。所以一般volume被用于持久化pod产生的数据。Kubernetes提供了众多的volume类型,包括emptyDir、hostPath、nfs、glusterfs、cephfs、ceph rbd等。具体可以参考官方文档。本篇文章我们简

2021-03-14 10:51:54 363

原创 什么是云原生?

云原生从字面意思上来看可以分成云和原生两个部分。云是和本地相对的,传统的应用必须跑在本地服务器上,现在流行的应用都跑在云端,云包含了IaaS,、PaaS和SaaS。原生就是土生土长的意思,我们在开始设计应用的时候就考虑到应用将来是运行云环境里面的,要充分利用云资源的优点,比如️云服务的弹性和分布式优势。那具体要怎么利用呢,请参考下图:微服务微服务解决的是我们软件开发中一直追求的低耦合+高内聚,记得有一次我们系统的接口出了问题,结果影响了用户的前台操作,于是黎叔拍案而起,灵魂发问:“为啥这两个会互

2021-02-07 14:11:29 326

原创 Mysql中间件系列Sharding-Sphere 之 Sharding-JDBC 快速入门

最近需要重构下公司SaaS系统的分库分表的中间件, 发现2020年刚孵化完毕的Sharding-Sphere还是不错的, 故有了此文.话不多说直接干货, 直接一个分库分表小demo献上!首先, 这个小demo做了什么事说明下:提供course课程的crud利用course的id进行 水平分表利用course所属的userId 进行水平分库Demo很简单, 结构如下:首先, maven依赖, 版本其实无所谓, 现在的兼容性比之前强了很多, 主要是要将shardingsphere支持引入,

2021-02-05 15:22:00 416

原创 Java Complier, JVM, JIT(Just In Time Compiler) 三者之间的关系

JavaComplier : 就是我们常见的javac指令, 将Java代码转化为字节码文件.JVM: java虚拟机, 负责 将bytecode 解释为本机机器语言运行JIT: JVM内部的实时编译器, 在字节码转换为机器指令时工作, 主要目的为性能优化.那么问题又来了, 为啥不用JIT全部编译成机器语言呢?有两个原因JIT是非常重量级的优化, 很消耗性能, 如果全部用JIT转换的话, 效率很低JIT需要runtime信息(只有程序运行起来才能获得)识别出热点片段(粒度为method).

2021-01-29 15:39:28 386

原创 Vue 双向绑定在已创建的实体的坑

vue不允许在已经创建的实例上添加新的根级响应式属性原因是:vue不允许在已经创建的实例上添加新的根级响应式属性,但可以通过set添加。所以解决办法就是把上面赋值这句代码修改为: for (var i = 0; i < vm.ext.patternList.length; i++) { if (vm.ext.patternList[i].newValue == null) { // 修改之前

2021-01-27 11:16:52 315

原创 利用序列化实现最优雅的深拷贝

最近碰到个线程安全问题, 遂想起是引用问题, 网上搬来的解决方案, 感觉很好, 记录一下 public static <T extends Serializable> T clone(T obj) throws IOException, ClassNotFoundException { ByteArrayOutputStream ous = new ByteArrayOutputStream(); ObjectOutput objectOutput = new

2021-01-21 17:36:33 355

原创 大白话过招Tomcat系列之: 致各位想要学习Tomcat的童鞋的一些话

首先 欢迎大家点击我的第一个付费栏目, 大白话过招系列之Tomcat架构解析先给各位鞠躬了在本系列文章中, 我将会用最接地气的文字描述, 结合我们身边最常见的现象和例子, 自底向上, 从JavaEE体系基座JVM开始, 一路向北, 途径JavaSE核心, 通往顶部JavaEE表层平台和框架, 去陈述一些晦涩难懂的架构, 规范, 协议知识, 既让大家充分的吸收Tomcat的设计精华, 又能在宏观的角度鸟瞰整个JavaEE体系.9块9你买不了吃亏, 9块9你买不了上当, 童叟无欺, 看过后悔者, csd

2020-12-02 12:51:54 545 1

原创 Spring Cloud Gateway 路由谓词工厂详解

Predicate是Java 8提供的一个函数式编程接口。谓词工厂…谓词工厂…, 听着玄乎, 其实就是if条件, 叫它trigger也挺合适谓词工厂有很多种AfterBeforeBetweenCookieHeaderHostMethodPathQueryRemoteAddr路由配置的两种形式1. 路由到指定URL示例1:通配spring: cloud: gateway: routes: - id: {唯一标识} uri:

2020-11-26 15:30:24 373 1

原创 SpringCloudGateway 实现微服务名称隐藏, url保护, token鉴权

在微服务中我们最好是要讲微服务名字隐藏起来, 这个demo中我使用了url转发实现,yml 和 过滤器代码如下.server: port: 8888spring: application: name: pns-gateway cloud: nacos: discovery: server-addr: localhost:8848 # register-enabled: true gateway: disc

2020-11-26 13:58:40 816 1

原创 Unable to find RoutePredicateFactory with name path

解决方法:predicates:- Path=/payment/get/**P 一定要大写

2020-11-26 12:18:19 1391 1

原创 关于SpringBoot定时任务懒加载的问题

今天偶然发现springboot的@Schedule定时任务不执行, 因为这个bean是被默认延迟加载的.不多说, 最终加上关闭懒加载搞定. @Lazy(false) @PostConstruct @Scheduled(fixedRate = 60 * 1000) public void refreshL2Cache() { .... }...

2020-11-20 11:26:12 761 1

dockerpackage.zip

解压后为两个文件 一个为mycat1.6.6 的linux安装包, 一个是mycat的dockerfile

2021-06-01

Sharding-Proxy

Mysql 分库中间件 Sharding-Proxy 下载

2021-02-23

elk 5.6.4 三件套

elk三件套

2020-10-27

HW7_HaoxuanLi.rar

小作业 自己留作备用

2019-12-17

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人 TA的粉丝

提示
确定要删除当前文章?
取消 删除