0%

参考文献

RabbitMQ介绍

RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。
AMQP :Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。

背景

RabbitMQ 是流行的开源消息队列系统,是 AMQP(Advanced Message Queuing Protocol 高级消息队列协议)的标准实现,用 erlang 语言开发。RabbitMQ 具有良好的性能和时效性,同时还能够非常好的支持集群和负载部署,非常适合在较大规模的分布式系统中使用。

安装

RabbitMQ 基于erlang。需要先安装erlang环境。

阅读全文 »

Redis

Redis全称:Remote Dictionary Server(远程数据服务)。Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

单实例安装

只是学习使用使用yum 方式安装比较快。而且centos自带官方源。

yum安装

  • yum install epel-release –下载fedora的epel仓库
  • yum install redis – 安装redis数据库
阅读全文 »

mongodb的安装方式比较简单,下面演示在CentOS7上用yum方式安装。

参考文献

使用yum方式安装

仅供学习参考,若在生产环境中部署请注意修改安全配置。

  • 整个mongodb(社区版)包含如下软件
软件名称 描述
mongodb-org-server 包含mongod守护程序和关联的配置和init脚本
mongodb-org-mongos 包含mongos守护程序
mongodb-org-shell 包含mongo shell,它是一个连接mongodb的命令行客户端,允许用户直接输入nosql语法管理数据库。
mongodb-org-tools 包含以下工具的MongoDB:数据导入、导出、备份、恢复等等
  • 创建yum源文件
1
vim /etc/yum.repos.d/mongodb-org-3.4.repo1
阅读全文 »

linux作为个人工作经常使用的系统、做下简单的记录方便以后工作参考。

ps

ps命令用于报告系统某个时间内进程的情况

  • 参数
1
2
3
4
5
-A : 所有的进程均显示出来
-a : 不与terminal有关的所有进程
-u : 有效用户的相关进程
-x : 一般与a参数一起使用,可以列出比较完整的信息。
-l : 较详细地将PID的信息列出。

案例

查询某程序的情况

1
2
3
$ [root@VM_115_109_centos ~]# ps -ef | grep mysqld
root 8013 17307 0 05:34 pts/0 00:00:00 grep --color=auto mysqld
mysql 28882 1 0 Apr02 ? 00:07:03 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

UID PID PPID C STIME TTY TIME CMD (类目描述)

  • UID 程序被该 UID 所拥有
  • PID 就是这个程序的 ID
  • PPID 则是其上级父程序的ID
  • C CPU 使用的资源百分比
  • STIME 系统启动时间
  • TTY 登入者的终端机位置
  • TIME 使用掉的 CPU 时间。
  • CMD 所下达的指令

查看内存占用前1的进程

  • ps auxw | head -1;ps auxw|sort -rn -k4|head -1
1
2
3
$  ps auxw | head -1;ps auxw|sort -rn -k4|head -1
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
mysql 28882 0.0 10.9 1143416 205484 ? Sl Apr02 7:20 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
  • 内存的单位是kb,VSZ是虚拟内存的占用,RSS是真实的内存的占用。

  • 命令分解:

  • ps auxw显示系统资源占用情况;

  • head -1表示显示第一列,即标题列;

  • sort -r 表示反向排序,-n表示按数字排序,-k4表示列的第4个字符。

查看CPU占用前1的进程

  • ps auxw|head -1;ps auxw|sort -rn -k3|head -1
1
2
3
4
5
6
7
$ ps auxw|head -1;ps auxw|sort -rn -k3|head -5
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1690 0.1 0.6 536692 12436 ? Sl Apr10 29:58 barad_agent
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 9 0.0 0.0 0 0 ? R Mar08 1:45 [rcu_sched]
root 884 0.0 0.0 110044 808 ttyS0 Ss+ Mar08 0:00 /sbin/agetty --keep-baud 115200 38400 9600 ttyS0 vt220
root 883 0.0 0.0 110044 788 tty1 Ss+ Mar08 0:00 /sbin/agetty --noclear tty1 linux
阅读全文 »

2014-10-10出发实习,职场萌新第一次去大型野外工地浪。长期在小城市里面突然跑到野外,关键还没啥人。放飞自我。

阅读全文 »

服务注册中心,给客户端提供可供调用的服务列表,客户端在进行远程服务调用时,根据服务列表然后选择服务提供方的服务地址进行服务调用。服务注册中心在分布式系统中大量应用,是分布式系统中不可或缺的组件,例如rocketmq的name server,hdfs中的namenode,dubbo中的zk注册中心,spring cloud中的服务注册中心eureka。 在spring cloud中,除了可以使用eureka作为注册中心外,还可以通过配置的方式使用zookeeper作为注册中心。既然这样,我们该如何选择注册中心的实现呢?

CAP定理

又被称作布鲁尔定理(Eric Brewer)它指出对于一个分布式计算系统来说,不可能同时满足以下三点:

  1. 强一致性(Consistency):系统在执行某项操作后数据状态仍然处于一致,例如在分布式系统中,更新操作执行成功后所有的用户都应该读取到最新的值,这样的系统被认为具有强一致性。
  2. 可用性(Availability):每一个操作总是能够在一定的时间内返回结果
  3. 分区容错性(Partition tolerance):单个节点故障不应导致整个系统崩溃,也就是说尽管网络在节点之间丢弃(或延迟)任意数量的消息,但是系统继续操作。

根据CAP原理将数据库分成了满足CA原则、满足CP原则和满足AP原则三大类

  1. CA:单点集群,满足一致性,可用性,通常在可扩展性上不太强大,比如RDB。
  2. CP:满足一致性和分区容错性,通常性能不是特别高,如分布式数据库。
  3. AP:满足可用性和分区容错性,通常可能对一致性要求低一些,如大多数的NoSQL。

BASE(Basically Available,Soft-state,Eventual consistency)

eBay的架构师Dan Pritchett源于对大规模分布式系统的实践总结,在ACM上发表文章提出BASE理论,BASE理论是对CAP理论的延伸,核心思想是即使无法做到强一致性(Strong Consistency,CAP的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)。

  1. 基本可用(Basically Available):系统能够基本运行并一直提供服务。
  2. 软状态(Soft-state):系统不要求一直保持强一致状态。
  3. 最终一致性(Eventual consistency):系统需要在某一时刻后达到一致性要求。

Zookeeper保证CP

  • 当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是zk会出现这样一种情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题使得zk集群失去master节点是较大概率会发生的事,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。

Eureka保证AP

  • Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Eureka注册或如果发现连接失败,则会自动切换至其它节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性),只不过查到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,此时会出现以下几种情况:

    1. Eureka不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
    2. Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
    3. 当网络稳定时,当前实例新的注册信息会被同步到其它节点中
  • 因此, Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像zookeeper那样使整个注册服务瘫痪。

阅读全文 »

Centos7的yum源中默认是没有mysql,因为现在已经用mariaDB代替mysql了。

安装前检查

检查linux系统版本

1
2
[root@localhost backup]# cat /etc/system-release
CentOS Linux release 7.4.1708 (Core)

检查是否已经安装mysql

1
[root@localhost backup]# rpm -qa | grep mysql
  • 如果存在Mysql可以考虑卸载

    1
    rpm -e --nodeps mysql-connector-odbc-x.x.x-x.el7.x86_64

    将/var/lib/mysql文件夹下的所有文件都删除干净。

检查是否安装mariaDB

阅读全文 »

​ 使用git进行合并分支说难也不难,因为就使用一下那几个命令而已!但是不小心操作总会有一些难以预料的问题出现、但是coder们总是会做出奇怪的举动。

​ 合并分支的时候O(∩_∩)O

合并分支

快速了解下分支流程。

​ 分支类似科幻电影里面经常出现的平行宇宙,只是分支之间还能合并。

​ git默认的是master分支,如果所有的开发都在master分支,这其实非常操蛋。这么吊的工具怎么可能没有好的分支策略。

  • 正常分支

    • origin/master:主分支
    • origin/develop:开发分支

      em 首先代码库默认有一个,且只有一个主分支Master,这个分支是仓库初始化的时候默认创建的。但实际上还有另一主分支 develop(开发主分支)、只是很多开发并不会启用develop分支。当develop分支上代码达到一定稳定的时候,所有的改动就会被合并到master中。并用一个发行版来标记它。所以每当被合并到master中就意味着一次release版本发布。这个时候才会使用(hook script)钩子去自动构建我们的项目、并部署正式服务器。

  • 临时分支

    • feature:功能分支(特征分支)
    • release:预发布分支(发行分支)
    • fixbug:修补bug分支(热补丁分支)

      为什么会有临时分支这种东西,上面说到主分支是用来管理重大版本发布的。日常的开发应该是在另外一条分支上进行develop,而临时分支是在develop分离出来做迭代以及bug修复的。达到阶段目标在合并到develop分支当中。


阅读全文 »

  • 本章内容为早期笔记迁移。
  • 阅读提醒,权限root.操作流程并位遵循安全规则;线上环境请勿模仿。

文件存放位置。

  • opt
    • backup
    • javahome
    • mavenhome
    • gradlehome
1
mkdir -p /opt/{backup,javahome,mavenhome,gradlehome}

相关基础程序安装

阅读全文 »

本章是整理知识内容,为强化知识长期更新。

Linked List

  • 链表即是由节点(Node)组成的线性集合,每个节点可以利用指针指向其他节点。它是一种包含了多个节点的、能够用于表示序列的数据结构。
  • 单向链表: 链表中的节点仅指向下一个节点,并且最后一个节点指向空。
  • 双向链表: 其中每个节点具有两个指针 p、n,使得 p 指向先前节点并且 n 指向下一个节点;最后一个节点的 n 指针指向 null。
  • 循环链表:每个节点指向下一个节点并且最后一个节点指向第一个节点的链表。
  • 时间复杂度:
    • 索引: O(n)
    • 搜索: O(n)
    • 插入: O(1)
    • 移除: O(1)

LinkedList 是是一个有序的集合,是Collection的实现类之一。

概述

  • 双链表 LinkedList 是 Java Collecion Framework成员之一。
  • 双链表 是List和Deque的接口的实现。
  • 在内部,它是使用双链表数据结构实现的。
  • 它支持重复的元素。它没有实现RandomAccess接口。所以我们只能按顺序访问元素。它不支持随机访问元素。
  • 相对与ArrayList它 删除 和添加 速度会快很多。但是遍历就要慢一些。
  • 它以插入顺序存储或维护它的元素。

链表

阅读全文 »

本章是整理知识内容,为强化知识长期更新。

List 是是一个有序的集合,是Collection的实现类之一。

概述

  • list接口是Java Collection Framework的成员。
  • 列队允许添加重复的元素。
  • 列队允许null存在。
  • 列队是从0开始,也就是列队头元素的下标是0。
  • 列队支持泛型,这样可以避免ClassCastException异常。

数组与数组列表

阅读全文 »

刚才学习SpringAop的时候觉得好强大

演示代码

演示效果

  • 启动代码
1
2
3
  docker-run curl http://localhost:9003/aop/

{"code":"200"}%
  • Console
1
2
[XNIO-1 task-1] [LogsAspect.java : 50]   annotationAop value index 
[XNIO-1 task-1] [LogsAspect.java : 50] annotationAop value index

Spring Aop

AOP(Aspect-Oriented Programming:⾯向切⾯编程)能够将那些与业务⽆关,却为业务模块所共同调⽤的逻辑或责任(例如事务处理、⽇志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

  • Spring Aop是运行时增强。
  • Cglib Aop是编译器增强。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

/**
* 是否要创建基于子类 (CGLIB) 的代理,而不是创建标准的基于 Java 接口的代理。 默认值为false 。
*/
boolean proxyTargetClass() default false;

/**
* org.springframework.aop.framework.AopContext类进行检索。 默认关闭
*/
boolean exposeProxy() default false;

}

Spring注解

1
2
3
4
5
6
7
@Aspect //定义切面:切面由切点和增强(引介)组成(可以包含多个切点和多个增强),它既包括了横切逻辑的定义,也包括了连接点的定义,SpringAOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的链接点中。
@Pointcut //定义切点:切点是一组连接点的集合。AOP通过“切点”定位特定的连接点。通过数据库查询的概念来理解切点和连接点的关系再适合不过了:连接点相当于数据库中的记录,而切点相当于查询条件。
@Before // 在目标方法被调用之前做增强处理,@Before只需要指定切入点表达式即可。
@AfterReturning //在目标方法正常完成后做增强,@AfterReturning除了指定切入点表达式后,还可以指定一个返回值形参名returning,代表目标方法的返回值。
@Afterthrowing //主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还可以指定一个throwing的返回值形参名,可以通过该形参名来访问目标方法中所抛出的异常对象。
@After //在目标方法完成之后做增强,无论目标方法时候成功完成。@After可以指定一个切入点表达式。
@Around //环绕通知,在目标方法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint。

pom依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

代码

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

package cn.z201.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @author z201.coding@gmail.com
**/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationAop {

String value();

}


package cn.z201.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
* @author z201.coding@gmail.com
**/
@Component
@Aspect
@Slf4j
public class LogsAspect {

@Pointcut("@annotation(cn.z201.aop.AnnotationAop)")
private void cutMethod() {

}

/**
* 异常通知:目标方法抛出异常时执行
*/
@AfterThrowing("cutMethod()")
public void afterThrowing(JoinPoint joinPoint) {
log.info("after throwing");
}

/**
* 环绕通知:灵活自由的在目标方法中切入代码
*/
@Before("cutMethod()")
public void before(JoinPoint joinPoint) throws Throwable {
// 获取目标方法的名称
String methodName = joinPoint.getSignature().getName();
// 获取方法传入参数
Object[] params = joinPoint.getArgs();
if (null != params && params.length != 0) {
log.info(" method name {} args {}", methodName, params[0]);
}
// 执行源方法
AnnotationAop annotationAop = getDeclaredAnnotation(joinPoint);
if (null != annotationAop) {
log.info(" annotationAop value {} ", annotationAop.value());
}
}

/**
* 获取方法中声明的注解
*
* @param joinPoint
* @return
* @throws NoSuchMethodException
*/
public AnnotationAop getDeclaredAnnotation(JoinPoint joinPoint) throws NoSuchMethodException {
// 获取方法名
String methodName = joinPoint.getSignature().getName();
// 反射获取目标类
Class<?> targetClass = joinPoint.getTarget().getClass();
// 拿到方法对应的参数类型
Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
// 根据类、方法、参数类型(重载)获取到方法的具体信息
Method objMethod = targetClass.getMethod(methodName, parameterTypes);
// 拿到方法定义的注解信息
AnnotationAop annotation = objMethod.getDeclaredAnnotation(AnnotationAop.class);
// 返回
return annotation;
}

}


package cn.z201.aop;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
* @author z201.coding@gmail.com
**/
@RestController
public class AppApplicationController {

@RequestMapping(value = "")
@AnnotationAop(value = "index")
public Object index() {
Map<String, Object> data = new HashMap<>();
data.put("code", "200");
return data;
}
}

END

2016年国庆的时候在重庆玩了几天、照片放手机里面好久了。时间有点久了,忘记具体都干啥了。留下照片回忆咯。

嗯晚上到的。

旅馆

阅读全文 »