常用Alfred工具

I. Alfred工具

alfred可以说是mac上必备的一个app了,可以极大的提高工作效率,再加上它支持自定义实现各种扩展,完全可以满足大部分的需求场景了

1. 安装

首先下载安装包,推荐一个神奇的网站,下载各种mac的破解软件,工具下载链接: http://xclient.info/s/alfred.html

破解方式:

  • 点击下载包里面的keygen
  • 点击patch,会打开目录,选择alfred,点击激活
  • 重启alfred即可

2. 几个插件

下载包内直接包含了所有的流程和源码,也没什么好具体说的,下载完毕之后双击即可

a. 日期与时间戳

点击下载:time.alfredworkflow

demo: time

b. md5

点击下载: md5.alfredworkflow

demo: md5

c. url编码

点击下载: URL编码.alfredworkflow

demo: url

d. 分库分表

点击下载: table.alfredworkflow

demo: md5

II. 其他

个人博客: Z+|blog

基于hexo + github pages搭建的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

声明

尽信书则不如,已上内容,纯属一家之言,因本人能力一般,见识有限,如发现bug或者有更好的建议,随时欢迎批评指正

扫描关注

QrCode

常用Popclip工具

I. PopClip工具

PopClip是mac上的一个工具集,最大的特点就是扩展,复制一段文本,然后根据你的需求写插件,把赋值的文本作为输出,做一些你想干的事

基于PopClip,也写了一些小工具,主要是php写的,写插件的教程还是比较简单的,一个配置文件Config.plist和一个脚本文件xxx.php即可

1. 实现一个插件流程

以JSON格式序列化为demo进行演示,如何从0到1创建一个popclip插件,先看一下最终的成品

img

一个插件的文件比较简单,主要有两个

  • Config.plist
  • 具体的脚本文件

a. 配置文件

下面是一个实际的配置,里面指定了两个脚本:

  • 第一个是 json2str.php,这个脚本实现将json转换为单行字符串,在插件上显示的名字就是 JsonStr, 采用的php编写实现
  • 第二个是 str2json.php

需要注意的是里面正则规则,这个主要是用来表示当你划中一段文本之后,是否会出现这个插件的规则(比如时间戳和日期的相互转换,只有选中纯数字时,才支持时间戳转日期)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Actions</key>
<array>
<dict>
<key>After</key>
<string>paste-result</string>
<key>Regular Expression</key>
<!-- 正则匹配规则,*号表示任意选中的内容都会激活这个插件 -->
<string>*</string>
<key>Script Interpreter</key>
<string>/usr/bin/php</string>
<key>Shell Script File</key>
<!-- 执行具体逻辑的脚本名 -->
<string>json2str.php</string>
<key>Title</key>
<!-- 插件的name -->
<string>JsonStr</string>
</dict>
<dict>
<key>After</key>
<string>paste-result</string>
<key>Regular Expression</key>
<string>*</string>
<key>Script Interpreter</key>
<string>/usr/bin/php</string>
<key>Shell Script File</key>
<string>str2json.php</string>
<key>Title</key>
<string>StrJson</string>
</dict>
</array>
<key>Extension Description</key>
<!-- 描述 -->
<string>remove json space or stringfy json str</string>
<key>Extension Name</key>
<string>JSON</string>
<key>Credits</key>
<array>
<dict>
<key>Link</key>
<string>mailto:bangzewu@126.com</string>
<key>Name</key>
<string>Json序列化</string>
</dict>
</array>
<key>Extension Identifier</key>
<string>popclip.extension.json-covert</string>
<key>Required Software Version</key>
<integer>695</integer>
</dict>
</plist>

b. 脚本文件

这个里面就是写具体的业务逻辑,一般是将粘贴板中的内容作为输入,然后进行一段业务逻辑,然后输出到粘贴板内

如str2json.php

1
2
3
4
5
6
7
8
<?php
$input=getenv("POPCLIP_TEXT");
if(empty($input)) {
echo '';
} else {
$param = json_decode($input);
echo json_encode($param, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
}

注意第一行,获取输入 $input=getenv("POPCLIP_TEXT");, 不同的脚本有不同的获取方式

输出就比较简单了,传统的输出方法,会重写到粘贴板内 echo 'xxx';

c. 打包

上面完成之后,就是打包安装了,流程如下:

  • 新建一个文件夹,后缀为.popclipext,将.plist和脚本文件拷贝到新的文件夹下
  • 压缩: zip -r xxx.popclipextz xxx.popclipext/
  • 双击上面生成的文件,确认安装即可

说明: 上面新建的文件夹,一定要以.popclipext结尾

2. 我的插件

a. base64编码

作用:实现base64编码解码

源码地址: base64

demo: base64

b. 日期&时间戳

作用:实现日期和时间戳的相互转换

源码地址: date

demo: deom

c. unicode字符转中文

源码 : unicode

d. json格式化

源码: json

e. url编码解码

源码: url


II. 其他

工程地址

所有的插件都可以访问: PopClip

个人博客: Z+|blog

基于hexo + github pages搭建的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

声明

尽信书则不如,已上内容,纯属一家之言,因本人能力一般,见识有限,如发现bug或者有更好的建议,随时欢迎批评指正

扫描关注

QrCode

常用Chrome工具

I. Chrome常用插件

记录下使用到的Chrome插件,有些挺有意思的东西

1. Website IP

在网页的右下角(or左下角)显示当前网页的服务器IP,用来判断当前的系统的工作环境非常有用,特别是在线下、预发和生产环境的切换时,判断host是否切换的时候

2. Adblock Plus

拦截小广告

3. Adkill and Media download

拦截视频广告,我常逛的优酷,腾讯视频,爱奇艺,芒果的视频广告都被可以被吃掉,节省两分钟的等待时间

4. GitCodeTree

码云提供的gitee,侧边栏提供一个直接查看代码的树状结构

5. JSON Editor

写json的插件

6. Json Handler

json结构化,针对请求直接返回json串的场景用起来比较爽,除了结构化输出之外,还可以修改json串内容,个人感觉比JSONView好用

7. Octotree

github源码视图工具,和前面的 GitCodeTree 差不多

8. Postman

模拟各种http请求

9. Vimium

以vim的方式操作浏览器页面,实现真正的无鼠标全键盘操作

10. 二维码(QR码)生成器(QR Code Generator)

当前网页生成一个二维码,方便手机打开

11. 捕捉网页截图 - FireShot

网页截图工具,可以截长图文,但是在网页特别长时,截取失败,有些时候用起来还可以

12. 掘金

覆盖默认的新打开标签页,显示一些有意思的git项目和掘金上的优秀博文

13. Encoder(自定义实现)

自己写的一个插件,主要是为了提供一些常见的转换, 源码&下载地址: Chrome-Coder

  • 时间戳和日期的相互转换
  • url编码解码
  • base64编码解码
  • unicode编码解码

14. Chrome-ImgRender

自己写的插件,源码&下载地址: Chrome-ImgRender

选择网页中的dom结构,输出图片的小工具,使用演示如:

II. 其他

个人博客: Z+|blog

基于hexo + github pages搭建的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

声明

尽信书则不如,已上内容,纯属一家之言,因本人能力一般,见识有限,如发现bug或者有更好的建议,随时欢迎批评指正

扫描关注

QrCode

Java学习之NIO相关

Java NIO学习小结

前面一篇主要学习了下IO的流式操作,接下来就是重头戏了,NIO,又称为New IO

当然也是得抱着问题来学习这个东西了,希望可以通过本文,可以学习到:

  • 什么是NIO
  • NIO相比较与IO有什么特点
  • 同步,非同步,阻塞,非阻塞是什么鬼
  • 几种IO模型

Java学习之IO相关

Java IO学习小结

IO操作算是java的一个基本知识点了,比如我们常见的网络IO,文件读写等,而且这一块基本上大家并不会频繁的来操作,大多会用一些封装得好用的工具来代替,某些时候真的需要做的时候,基本上也很难一下子很顺利的写完

本篇将主要集中在:

  • 几种IO分类
  • 字节IO和字符IO的转换
  • 装饰类IO是什么
  • 序列化的实现机制

JVM学习之垃圾回收机制

jvm的垃圾回收算法,除了我们熟悉的引用计数判断对象是否活着之外,其他还有那些有意思的东西呢?

总是听到的年轻代年老代又是啥?

传说中的YoungGC(MinorGC) 和 FullGC的时机是什么,又干了些啥?

熔断Hystrix使用尝鲜

熔断Hystrix使用尝鲜

当服务有较多外部依赖时,如果其中某个服务的不可用,导致整个集群会受到影响(比如超时,导致大量的请求被阻塞,从而导致外部请求无法进来),这种情况下采用hystrix就很有用了

出于这个目的,了解了下hystrix框架,下面记录下,框架尝新的历程

I. 原理探究

通过官网和相关博文,可以简单的说一下这个工作机制,大致流程如下

首先是请求过来 -> 判断熔断器是否开 -> 服务调用 -> 异常则走fallback,失败计数+1 -> 结束

下面是主流程图

流程图

1
2
3
4
5
6
7
8
9
10
graph LR
A(请求)-->B{熔断器是否已开}
B --> | 熔断 | D[fallback逻辑]
B --> | 未熔断 | E[线程池/Semphore]
E --> F{线程池满/无可用信号量}
F --> | yes | D
F --> | no | G{创建线程执行/本线程运行}
G --> | yes | I(结束)
G --> | no | D
D --> I(结束)

熔断机制主要提供了两种,一个是基于线程池的隔离方式来做;还有一个则是根据信号量的抢占来做

线程池方式 : 支持异步,支持超时设置,支持限流

信号量方式 : 本线程执行,无异步,无超时,支持限流,消耗更小

基本上有上面这个简单的概念之后,开始进入我们的使用测试流程

II. 使用尝鲜

1. 引入依赖

1
2
3
4
5
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.12</version>
</dependency>

2. 简单使用

从官方文档来看,支持两种Command方式,一个是基于观察者模式的ObserverCommand, 一个是基本的Command,先用简单的看以下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
public class HystrixConfigTest extends HystrixCommand<String> {

private final String name;

public HystrixConfigTest(String name, boolean ans) {
// 注意的是同一个任务,
super(Setter.withGroupKey(
// CommandGroup是每个命令最少配置的必选参数,在不指定ThreadPoolKey的情况下,字面值用于对不同依赖的线程池/信号区分
HystrixCommandGroupKey.Factory.asKey("CircuitBreakerTestGroup"))
// 每个CommandKey代表一个依赖抽象,相同的依赖要使用相同的CommandKey名称。依赖隔离的根本就是对相同CommandKey的依赖做隔离.
.andCommandKey(HystrixCommandKey.Factory.asKey("CircuitBreakerTestKey_" + ans))
// 当对同一业务依赖做隔离时使用CommandGroup做区分,但是对同一依赖的不同远程调用如(一个是redis 一个是http),可以使用HystrixThreadPoolKey做隔离区分
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("CircuitBreakerTest_" + ans))
.andThreadPoolPropertiesDefaults( // 配置线程池
HystrixThreadPoolProperties.Setter()
.withCoreSize(12) // 配置线程池里的线程数,设置足够多线程,以防未熔断却打满threadpool
)
.andCommandPropertiesDefaults( // 配置熔断器
HystrixCommandProperties.Setter()
.withCircuitBreakerEnabled(true)
.withCircuitBreakerRequestVolumeThreshold(3)
.withCircuitBreakerErrorThresholdPercentage(80)
// .withCircuitBreakerForceOpen(true) // 置为true时,所有请求都将被拒绝,直接到fallback
// .withCircuitBreakerForceClosed(true) // 置为true时,将忽略错误
// .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE) // 信号量隔离
.withExecutionIsolationSemaphoreMaxConcurrentRequests(20)
.withExecutionTimeoutEnabled(true)
.withExecutionTimeoutInMilliseconds(200)
.withCircuitBreakerSleepWindowInMilliseconds(1000) //熔断器打开到关闭的时间窗长度
// .withExecutionTimeoutInMilliseconds(5000)
)
);
this.name = name;
}

@Override
protected String run() throws Exception {
System.out.println("running run():" + name + " thread: " + Thread.currentThread().getName());
int num = Integer.valueOf(name);
if (num % 2 == 0 && num < 10) { // 直接返回
return name;
} else if (num < 40) {
Thread.sleep(300);
return "sleep+"+ name;
} else { // 无限循环模拟超时
return name;
}
}
//
// @Override
// protected String getFallback() {
// Throwable t = this.getExecutionException();
// if(t instanceof HystrixRuntimeException) {
// System.out.println(Thread.currentThread() + " --> " + ((HystrixRuntimeException) t).getFailureType());
// } else if (t instanceof HystrixTimeoutException) {
// System.out.println(t.getCause());
// } else {
// t.printStackTrace();
// }
// System.out.println(Thread.currentThread() + " --> ----------over------------");
// return "CircuitBreaker fallback: " + name;
// }

public static class UnitTest {

@Test
public void testSynchronous() throws IOException, InterruptedException {
for (int i = 0; i < 50; i++) {
if (i == 41) {
Thread.sleep(2000);
}
try {
System.out.println("===========" + new HystrixConfigTest(String.valueOf(i), i % 2 == 0).execute());
} catch (HystrixRuntimeException e) {
System.out.println(i + " : " + e.getFailureType() + " >>>> " + e.getCause() + " <<<<<");
} catch (Exception e) {
System.out.println("run()抛出HystrixBadRequestException时,被捕获到这里" + e.getCause());
}
}

System.out.println("------开始打印现有线程---------");
Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
for (Thread thread : map.keySet()) {
System.out.println("--->name-->" + thread.getName());
}
System.out.println("thread num: " + map.size());

System.in.read();
}
}
}

使用起来还是比较简单的,一般步骤如下:

  • 继承 HsytrixCommand
  • 重载构造方法,内部需要指定各种配置
  • 实现run方法,这个里面主要执行熔断监控的方法

写上面的代码比较简单,但是有几个地方不太好处理

  1. 配置项的具体含义,又是怎么生效的?
  2. 某些异常不进入熔断逻辑怎么办?
  3. 监控数据如何获取?
  4. 如何模拟各种不同的case(超时?服务异常?熔断已开启?线程池满?无可用信号量?半熔断的重试?)

3. 实测理解

根据上面那一段代码的删删改改,貌似理解了以下几个点,不知道对误

a. 配置相关

  • groupKey 用于区分线程池和信号量,即一个group对应一个
  • commandKey 很重要,这个是用于区分业务
    • 简单来讲,group类似提供服务的app,command则对应app提供的service,一个app可以有多个service,这里就是将一个app的所有请求都放在一个线程池(or共享一个信号量)
  • 开启熔断机制,指定触发熔断的最小请求数(10s内),指定打开熔断的条件(失败率)
  • 设置熔断策略(线程池or信号量)
  • 设置重试时间(默认熔断开启后5s,放几个请求进去,看服务是否恢复)
  • 设置线程池大小,设置信号量大小,设置队列大小
  • 设置超时时间,设置允许超时设置

b. 使用相关

run方法是核心执行服务调用,如果需要某些服务不统计到熔断的失败率(比如因为调用姿势不对导致服务内部的异常抛上来了,但是服务本身是正常的),这个时候,就需要包装下调用逻辑,将不需要的异常包装到 HystrixBadRequestException 类里

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
protected String run() {
try {
return func.apply(route, parameterDescs);
} catch (Exception e) {
if (exceptionExcept(e)) {
// 如果是不关注的异常case, 不进入熔断逻辑
throw new HystrixBadRequestException("unexpected exception!", e);
} else {
throw e;
}
}
}

c. 如何获取失败的原因

当发生失败时,hystrix会把原生的异常包装到 HystrixRuntimeException 这个类里,所以我们可以在调用的地方如下处理

1
2
3
4
5
6
7
try {
System.out.println("===========" + new HystrixConfigTest(String.valueOf(i), i % 2 == 0).execute());
} catch (HystrixRuntimeException e) {
System.out.println(i + " : " + e.getFailureType() + " >>>> " + e.getCause() + " <<<<<");
} catch (Exception e) {
System.out.println("run()抛出HystrixBadRequestException时,被捕获到这里" + e.getCause());
}

当定义了fallback逻辑时,异常则不会抛到具体的调用方,所以在 fallback 方法内,则有必要获取对应的异常信息

1
2
// 获取异常信息
Throwable t = this.getExecutionException();

然后下一步就是需要获取对应的异常原因了,通过FailureType来表明失败的根源

1
((HystrixRuntimeException) t).getFailureType()

d.如何获取统计信息

hystrix自己提供了一套监控插件,基本上公司内都会有自己的监控统计信息,因此需要对这个数据进行和自定义,目前还没看到可以如何优雅的处理这些统计信息

4. 小结

主要是看了下这个东西可以怎么玩,整个用下来的感觉就是,设计的比较有意思,但是配置参数太多,很多都没有完全摸透

其次就是一些特殊的case(如监控,报警,特殊情况过滤)需要处理时,用起来并不是很顺手,主要问题还是没有理解清楚这个框架的内部工作机制的问题

III. 其他

个人博客: Z+|blog

基于hexo + github pages搭建的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

声明

尽信书则不如,已上内容,纯属一家之言,因本人能力一般,见识有限,如发现bug或者有更好的建议,随时欢迎批评指正

扫描关注

QrCode

JVM学习之内存结构

JVM学习之内存结构

java运行时对象创建在什么地方?堆和栈空间又有什么区别?听闻已久的Young,Old区又是什么鬼?听说有个常量池,这个又是啥

要想在脑海中清晰的布局一个java类在加载到使用的过程中,整个类生命周期中,各项数据究竟最终落在哪个板块上,就需要了解下JVM的内存区域了

JVM学习之Java类的加载机制

JVM学习之Java类的加载机制

平常我们使用java的多,深入到jvm层的机会却很少,平时若不关注,也不会清楚java文件编译后的class文件是如何被jvm加载到内存,如何进行初始化,如何进行运行的

因此这里主要学习的目标就是class文件的加载,会包含以下内容:

  • 什么是类加载
  • 类加载的过程
  • 什么时候触发类加载
  • 类加载器
  • 双亲委托机制

Chrome插件之DomToImage实现

I. 说明

有些时候,看到一些网页的信息时,想分享给小伙伴,一般直接用截图工具来做,但是当分享的内容比较长时,截图就比较蛋疼了,所以想着做了这么个插件

可以将网页中任意一个dom结构,渲染为图片

JQuery 实战笔记一

jquery实战笔记

写前端控制台中,实际遇到的不会的,通过查询解决的记录,汇总记录下来,一期主要包括:

  • 标签隐藏显示
  • 时间戳转换
  • radio单选框选中获取
  • 动态修改placeholder值
  • 判断字符串是否为数字类型
  • tab标签页实现
  • 标签点击事件
  • jquery跳转链接
  • jquery 修改图片url
  • 图片加边框
  • 实现一个可检索的table
  • 表格内容固定
  • input回车响应

Java并发学习之线程池ThreadPoolExecutor的小结

Java并发学习之线程池ThreadPoolExecutor的小结

本篇博文将带着问题来回顾小结多线程池相关的知识点

  1. 线程池的几种创建方式
  2. 线程池的优点是什么
  3. 应用场景
  4. 如何使用
  5. 实现原理
  6. 异常状况怎么处理
  7. 线程池中任务的提交执行后,到线程执行,执行完成的整个流程逻辑
  8. 线程池中的线程回收机制

7. 报警系统QuickAlarm之默认报警规则扩展

本篇主要是扩展默认的报警规则,使其能更加友好的支持同时选择多种报警方式

扩展遵循两个原则

  • 不影响原有的配置文件格式
  • 简化规则解析复杂度

借助GitHub搭建属于自己的maven仓库教程

I. 背景

在Github上也写了不少的项目了,然后经常遇到的一个问题就是,很多自己写的项目,希望在另外一个项目中使用时,只能把这个项目下载下来,相当之不方便

因为大多数的java后端项目都是基于maven管理依赖的,所以就希望能有一个公共的maven仓库,可以把自己的项目扔进去,然后再应用就方便很多了

基于此,就有了本文这个教程了

II. 实现步骤

1. github仓库建立

新建一个repository的前提是有github帐号,默认看到本文的是有帐号的

首先是在github上新建一个仓库,命令随意,如我新建项目为

2. 配置本地仓库

本地指定一个目录,新建文件夹 maven-repository, 如我的本地配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
## 进入目录
cd /Users/yihui/GitHub

## 新建目录
mkdir maven-repository; cd maven-repository

## 新建repository目录
# 这个目录下面就是存放我们deploy的项目相关信息
# 也就是说我们项目deploy指定的目录,就是这里
mkdir repository

## 新增一个readme文档
# 保持良好的习惯,每个项目都有一个说明文档
touch README.md

这个目录结构为什么是这样的?

我们直接看maven配置中默认的目录结构,同样拷贝一份出来而已

3. 仓库关联

将本地的仓库和远程的github仓库关联起来,执行的命令也比较简单了

1
2
3
4
git add .
git commit -m 'first comit'
git remote add origin https://github.com/liuyueyi/maven-repository.git
git push -u origin master

接着就是进行分支管理了

  • 约定将项目中的snapshot版,deploy到仓库的 snapshot分支上
  • 约定将项目中的release版,deploy到仓库的 release分支上
  • master分支管理所有的版本

所以需要新创建两个分支

1
2
3
4
5
6
7
8
## 创建snapshot分支
git checkout -b snapshot
git push origin snapshot
# 也可以使用 git branch snapshot , 我通常用上面哪个,创建并切换分支

## 创建release分支
git checkout -b release
git push origin release

4. 项目deploy

项目的deploy,就需要主动的指定一下deploy的地址了,所以我们的deploy命令如下

1
2
## deploy项目到本地仓库
mvn clean deploy -Dmaven.test.skip -DaltDeploymentRepository=self-mvn-repo::default::file:/Users/yihui/GitHub/maven-repository/repository

上面的命令就比较常见了,主要需要注意的是file后面的参数,根据自己前面设置的本地仓库目录来进行替换

5. deploy脚本

每次进行上面一大串的命令,不太好记,特别是不同的版本deploy到不同的分支上,主动去切换分支并上传,也挺麻烦,所以就有必要写一个deploy的脚本了

由于shell实在是不太会写,所以下面的脚本只能以凑合能用来说了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/bin/bash

if [ $# != 1 ];then
echo 'deploy argument [snapshot(s for short) | release(r for short) ] needed!'
exit 0
fi

## deploy参数,snapshot 表示快照包,简写为s, release表示正式包,简写为r
arg=$1

DEPLOY_PATH=/Users/yihui/GitHub/maven-repository/
CURRENT_PATH=`pwd`

deployFunc(){
br=$1
## 快照包发布
cd $DEPLOY_PATH
## 切换对应分支
git checkout $br
cd $CURRENT_PATH
# 开始deploy
mvn clean deploy -Dmaven.test.skip -DaltDeploymentRepository=self-mvn-repo::default::file:/Users/yihui/GitHub/maven-repository/repository

# deploy 完成,提交
cd $DEPLOY_PATH
git add -am 'deploy'
git push origin $br

# 合并master分支
git checkout master
git merge $br
git commit -am 'merge'
git push origin master
cd $CURRENT_PATH
}

if [ $arg = 'snapshot' ] || [ $arg = 's' ];then
## 快照包发布
deployFunc snapshot
elif [ $arg = 'release' ] || [ $arg = 'r' ];then
## 正式包发布
deployFunc release
else
echo 'argument should be snapshot(s for short) or release(r for short). like: `sh deploy.sh snapshot` or `sh deploy.sh s`'
fi

将上面的脚本,考本到项目的根目录下,然后执行

1
2
3
4
5
6
7
8
chmod +x deploy.sh

## 发布快照包
./deploy.sh s
# sh deploy.sh snapshot 也可以

## 发布正式包
./deploy.sh r

基于此,整个步骤完成

III. 使用

上面仓库的基本搭建算是ok了,然后就是使用了,maven的pom文件应该怎么配置呢?

首先是添加仓库地址

添加仓库

如果要区分snapshot和release的话,如下配置

1
2
3
4
5
6
7
8
9
10
<repositories>
<repository>
<id>yihui-maven-repo-snap</id>
<url>https://raw.githubusercontent.com/liuyueyi/maven-repository/snapshot/repository</url>
</repository>
<repository>
<id>yihui-maven-repo-release</id>
<url>https://raw.githubusercontent.com/liuyueyi/maven-repository/release/repository</url>
</repository>
</repositories>

如果不care的话,直接添加下面的即可

1
2
3
4
5
6
<repositories>
<repository>
<id>yihui-maven-repo</id>
<url>https://raw.githubusercontent.com/liuyueyi/maven-repository/master/repository</url>
</repository>
</repositories>

仓库配置完毕之后,直接引入依赖即可,如依赖我的Quick-Alarm包,就可以添加下面的依赖配置

1
2
3
4
5
<dependency>
<groupId>com.hust.hui.alarm</groupId>
<artifactId>core</artifactId>
<version>0.1</version>
</dependency>

IV. 其他

个人博客: Z+|blog

基于hexo + github pages搭建的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

声明

尽信书则不如,已上内容,纯属一家之言,因本人能力一般,见识有限,如发现bug或者有更好的建议,随时欢迎批评指正,我的微博地址: 小灰灰Blog

扫描关注

QrCode

6. 报警系统QuickAlarm使用手册

本文将主要说明QuickAlarm该如何使用,以及使用时需要注意事项

5. 报警系统QuickAlarm之频率统计及接口封装

前面将报警规则的制定加载解析,以及报警执行器的定义加载和扩展进行了讲解,基本上核心的内容已经完结,接下来剩下内容就比较简单了

  • 报警频率的统计
  • 报警线程池
  • 对外封装统一可用的解耦

4. 报警系统QuickAlarm之报警规则解析

前面两篇分别说了报警执行器和报警规则的定义及用户扩展加载,接下来就是比较核心的一块了,如何将报警规则和报警执行器关联起来,即当发生报警时,应该call哪一个报警执行器

3. 报警系统QuickAlarm之报警规则的设定与加载

前面一篇是报警执行器的定义与加载已经完成,但与之对应的报警规则有是如何定义和加载的呢?

此外,既然命名为规则,那么就需要有对应的解析器,以根据报警规则和报警类型等相关输入条件,来选择对应的报警执行器,因此本文主要包括的内容就比较清晰了

  • 报警规则的定义
  • 报警规则的加载
  • 报警规则的解析以及报警执行器选择

2. 报警系统QuickAlarm之报警执行器的设计与实现

根据前面一篇总纲的博文,将整体结构划分为了四大块,本文则主要目标集中在第一块,报警执行器(AlarmExecute)的设计与加载上了

主要的关注点无外乎 定义-》加载-》实现逻辑三块了:

  • AlarmExecute 的接口定义
  • 如何加载用户自定义的AlarmExecute
  • AlarmExecute的内部实现

1. 报警系统QuickAlarm设计总纲

背景

日常的系统中,报警是不可缺少的一环,目前报警方式很多,最常见的有直接打日志,微信报警,短信报警,邮件报警等;而涉及到报警,一般不可避免的需要提前设置一些基本信息,如报警方式,报警频率,报警用户,开关等;

另外一个常见的问题是一般采用的是单一的报警方式,比如不管什么类型的报警全部都用短信方式触达,然后就会发现手机时常处于被淹没的状态了,久而久之对报警短信就不会敏感了

Your browser is out-of-date!

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

×