[DevOps] 使用Azure pipeline + Github为你的应用构建CI/CD流水线

2020/11 upd :文章应该咕咕咕了,但是具体内容可以参照我的视频

什么是 DevOps ?什么是 CI/CD 流水线?

这个问题由于网上已经有很多很好的文章了,所以我这里就不再详细写了。大家可以自行参考。
什么是DevOps?什么是 CI/CD 流水线?

我归纳一下,

  1. DevOps是敏捷开发的一种主流实现方式,相比于传统的瀑布模型,DevOps为我们快速开发应用,快速发布应用,快速部署应用提供了一种方法论。
  2. DevOps中大致有如下几个环节
    1. Version Control (版本控制)
    2. Continuous Integration(持续集成)
    3. Continuous Delivery (持续交付)
    4. Continuout Deployment(持续部署)

如何为你的应用搭建完整的 CI/CD 流水线

在这篇文章中,我们将使用 Git + Github + Docker + Azure pipeline 的组合来完成一个简单的 node 服务端应用的自动化流水线的搭建。

  1. 创建一个node应用

    1. 初始化项目

      npm init
    2. 安装typescript

      npm install -g typescript
    3. 初始化为TypeScript应用

      tsc --init
    4. 安装我们需要的 express 依赖

      npm install express @types/express
    5. 编写一个最简单的Web应用

[DevOps] 如何写一个可快速构建镜像的Dockerfile脚本

本文不针对刚接触Docker和DevOps的初学者,一些初级资料可以查阅——https://yeasy.gitbooks.io/docker_practice/introduction/what.html

在一个CI/CD工作流中,我们在本地修改代码并提交后,CI系统会自动构建我们的代码并运行单元测试来验证本次提交的可行性。而这个构建很多时候为了屏蔽平台以及环境的差异性,往往会使用Docker来构建。构建一个Docker image绕不开的话题就是Dockerfile脚本该怎么写。不同的项目事实上编写的Dockerfile遇到的痛点往往不一样。本文针对的痛点是——构建速度慢。针对这个问题,我们首先得了解一下Docker build中的cache机制。

浅析Java强大的动态Instrumention能力

前言

在前面的博客中,我写过一句话,叫做

Java世界里的一切东西都是在拼Java命令行参数

如果你使用IDEA,并且在运行 Java 代码时观察过 IDEA 帮我们拼出来的命令行参数,举个例子

D:\jdk8\jdk1.8.0_232\bin\java.exe "\"-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 201.4865.12\lib\idea_rt.jar=61840:C:\Program Files\JetBrains\IntelliJ IDEA 201.4865.12\bin\"" -Dfile.encoding=UTF-8 -classpath ( 省略一系列依赖Jar包 ) C:\Users\25959\Desktop\test\target\classes com.ayang818.test.Test

这是我运行一个很简单的程序,IDEA 帮我们拼出来的命令行参数,其中 -Dfile.encoding 和 -classpath 我们都很熟悉,一个是指定编码方式,另一个是指定 classpath 路径。但是有一个我们可能很陌生的参数,叫做 -javaagent , agent 翻译成中文是代理的意思。于是我开始了一天的探究过程。

常用的一些算法板子(持续更新)

持续更新的一些算法板子

更详细的题目或题解可以查看我的刷题仓库

序列化动态规划解题技巧

序列化动态规划解题技巧总结

序列化动态规划属于动态规划中的基础题,这类题目通常是一组序列。

这类题目一般有一种比较通用的状态转移方程
$$
dp[i][aa]=Option_1^{i-1}(dp[i-1][bb])+cast_i
$$
其实这种题目在代码上也有一些小技巧

  1. 如果使用递推时间代码,让动态规划有效状态的下表从 1 开始,把下表 0 让给一步决策都没有做的初始状态。通常这样做,可以让边界处理简单不少。
  2. 其次是主动转移和被动转移,主动转移是从一个状态去找这个这个状态可以转移到什么状态;被动转移是去找这个状态是由什么状态转移来的。

寒假开始啦! 开始进行Kugga的基础设施建设了!

寒假博客应该不怎么会更新了。我的Kugga计划也提上日程了。寒假里的一些知识记录部分会以文档的形式更新在Kugga-wiki上面,感兴趣也可以关注下。

maven模块化最小实践

为什么要进行maven模块化

在说模块化之前,不妨说说非模块化的项目是怎么样的,非模块化的项目往往是一个单体应用,他的目录结构如下

为什么说是单体的呢,事实上

  1. 上面看到的所有的包比如controller,mapper,utils,
    , 这些一个个应用里的功能都是业务的一部分,到时候打jar包的时候其实就是把这些所有的功能打到同一个jar包中。然后运行就可以了。
  2. 整个项目只有一个pom文件,功能与项目强耦合,代码复用能力差。

那么对于一个多模块项目来说呢,他的目录结构如下

使用0xff来保证二进制补码的一致性

写这篇文章的起因

本来今天在写浅析分布式唯一ID生成算法——snowflake的实现这篇博客的时候,写的好好的,但是写到一种生成方式

UUID.randomUUID().toString();

发现自己并不是很知道这个怎么实现的,然后点开了源码打算读一下。结果就发现了一段代码。

/*
* Private constructor which uses a byte array to construct the new UUID.
*/
private UUID(byte[] data) {
long msb = 0;
long lsb = 0;
assert data.length == 16 : "data must be 16 bytes in length";
for (int i=0; i<8; i++)
msb = (msb << 8) | (data[i] & 0xff);
for (int i=8; i<16; i++)
lsb = (lsb << 8) | (data[i] & 0xff);
this.mostSigBits = msb;
this.leastSigBits = lsb;
}

其中有一小段(下方代码段)我不是很理解有什么作用,因为data[i]的类型实际上是byte类型的,byte的十进制范围是-128-127,而0xff的十进制是15 * 16 + 16 = 256,转化为八位二进制就是11111111,我想着data[i] & 0xff的话是使用0xff做截取操作,但是byte转化为二进制的长度肯定在8位以内,所以这个截取操作第一眼看起来并没有什么用哈?

data[i] & 0xff

浅析分布式唯一ID生成算法——snowflake的实现

开头先放一个snowflake的实现——仓库地址

分布式唯一Id是什么

分布式唯一Id其实是一个分布式系统里面的一个不可或缺的元素,他一般具有如下几个特性

  • 同一业务的全局唯一性(globally unique)
  • 包含时间信息(timestamp)
  • 递增有序性(incremented and ordered)

分布式唯一Id有什么用

这样一个分布式唯一Id,在一个分布式系统中的作用都有些什么呢。

举个例子,比如说业务量大了要做分库分表了,拿MyCat这个中间件举例,你对接了MyCat这个中间件后,你是接触不到MyCat后面被取余策略或其他策略分离的表的。MyCat呈现给你的仍然是一张表,但是却是分离的表的合并。 那这个时候你后面的数据库的主键要是还是和单机的策略一样,仍然是普通的auto_increment 1的话,你的分割后的每张表都会有重复的Id。
比如说有一组订单表order_1, order_2

使用CGlib实现动态代理模式

前言

关于代理模式和使用JDK dynamic proxy实现的动态代理模式,已经在使用JDK dynamic proxy实现动态代理模式写过了,也说了Spring5之前使用的代理就是JDK默认的动态代理。然后我自己最近也在写一个框架——Agito。在自己实现AOP特性的时候,感觉使用JDK自带的动态代理并不容易实现我的需求,所以在技术选型的时候,我选择了CGlib这个字节码增强利器来实现动态代理。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×