日期: 2021 年 5 月 17 日

[IOS]——模糊搜索的实现

模糊搜索的实现(支持拼音搜索,汉字搜索,首字母搜索)
搜索是要用到UISearchBar
我做出的UISearchBar的效果

UISearchBar的代码实现
1.//首先要遵守协议
@interface weiboViewController ()<UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate>
2.//代码的实现
//搜索框
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@”sousuo”] style:0 target:self action:@selector(setUpsearch)];
_search = [[UISearchBar alloc] init];
//显示搜索框的cancel按钮
_search.showsCancelButton = YES;
//设置代理
_search.delegate = self;
//[UIApplication sharedApplication].statusBarFrame.size.height这是获取状态栏的高度
//self.navigationController.navigationBar.frame.size.height这是获取导航栏的高度
_search.frame = CGRectMake(0,[UIApplication sharedApplication].statusBarFrame.size.height+self.navigationController.navigationBar.frame.size.height-35, [UIScreen mainScreen].bounds.size.width, 35);
//把搜索框隐藏在navigationBar的后面
[self.navigationController.view insertSubview:_search belowSubview:self.navigationController.navigationBar];
//动画下拉搜索框的关键代码
//因为一开始搜索框是隐藏在navigationBar背后的,当时距离底部为35,那么我设置search下滑35就能完全地将search显示出来
[UIView animateWithDuration:1.0 animations:^{
self.search.transform = CGAffineTransformMakeTranslation(0, 35);
}];

 

重点来了!模糊搜索的实现(我已经将方法封装好,可以直接复制去测试!)
这是将搜索范围内的文本全部转成不带声调的拼音
//将汉字转变为拼音
– (NSString *)transformToPinyin:(NSString *)searchtext
{
//转成了可变字符串
NSMutableString *str = [NSMutableString stringWithString:searchtext];
//将汉字转变为拼音
CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformMandarinLatin,NO);
//再转换为不带声调的拼音
CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformStripDiacritics,NO);
//转变后的str每个字是旁边是有空格分开的
NSArray *pinyinArray = [str componentsSeparatedByString:@” “];
NSMutableString *allString = [NSMutableString new];
int count = 0;
//这是把汉字的拼音全部拼接起来
for (int i = 0; i < pinyinArray.count; i++)
{
for(int i = 0; i < pinyinArray.count;i++)
{
if (i == count) {
[allString appendString:@”#”];
//区分第几个字母
}
[allString appendFormat:@”%@”,pinyinArray[i]];
}
[allString appendString:@”,”];
count ++;
}
NSMutableString *initialStr = [NSMutableString new];
//这是把汉字的首字母拼接起来
for (NSString *s in pinyinArray)
{
if (s.length > 0)
{
[initialStr appendString: [s substringToIndex:1]];
}
}
[allString appendFormat:@”#%@”,initialStr];
[allString appendFormat:@”,#%@”,searchtext];
return allString;
}

由于上面方法是有局限性的,因为把搜索范围内的文本都转成的拼音都是小写的,因此我再提供一个方法来将你在搜索框输入的大写字母都转成小写字母
-(NSString *)changetoLower:(NSString *)str
{
for (NSInteger i=0; i<str.length; i++) {
if ([str characterAtIndex:i]>=’A’&&[str characterAtIndex:i]<=’Z’) {
char temp=[str characterAtIndex:i]+32;
NSRange range=NSMakeRange(i, 1);
str=[str stringByReplacingCharactersInRange:range withString:[NSString stringWithFormat:@”%c”,temp]];
}
}
return str;
}

docker swarm集群部署 portainer 管理实践

介绍

Swarm 在 Docker 1.12 版本之前属于一个独立的项目,在 Docker 1.12 版本发布之后,该项目合并到了 Docker 中,成为 Docker 的一个子命令。目前,Swarm 是 Docker 社区提供的唯一一个原生支持 Docker 集群管理的工具。它可以把多个 Docker 主机组成的系统转换为单一的虚拟 Docker 主机,使得容器可以组成跨主机的子网网络。

Swarm 是目前 Docker 官方唯一指定(绑定)的集群管理工具。Docker 1.12 内嵌了 swarm mode 集群管理模式。

准备

Docker 安装及配置

实现docker swarm集群需要多台服务器实现集群的,这里我准备了2台服务器,且操作系统都是 raspbian-stretch-lite,IP分别是:

  1. 1
  2. 2
  1. 192.168.2.101 rpi1
  2. 192.168.2.102 rpi2

 

2台服务器上分别执行以下命令,安装docker

配置apt

1
sudo nano /etc/apt/sources.list

将文件里的默认的官方软件源用# 注释掉,添加以下:

1
deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ stretch main contrib non-free rpi
1
sudo nano /etc/apt/sources.list.d/raspi.list

将文件里的默认的官方软件源用# 注释掉,添加以下:

1
deb http://mirrors.ustc.edu.cn/archive.raspberrypi.org/ stretch main ui

添加docker apt源

  1. 1
  2. 2
  3. 3
  1. echo “deb [arch=armhf] https://download.docker.com/linux/debian
  2. $(lsb_release -cs) stable” |
  3. sudo tee /etc/apt/sources.list.d/docker.list

配置Docker官方APT GPG key

1
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
1
sudo apt-key fingerprint 0EBFCD88

输出对比是否是一致的:

  1. 1
  2. 2
  3. 3
  4. 4
  1. pub 4096R/0EBFCD88 2017-02-22
  2. Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
  3. uid Docker Release (CE deb) <docker@docker.com>
  4. sub 4096R/F273FCD8 2017-02-22

 

更新apt

1
apt update

安装docker

1
sudo apt-get install docker-ce

docker配置国内镜像

在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  1. {
  2. “registry-mirrors”: [
  3. “https://registry.docker-cn.com”
  4. ]
  5. }

 

docker 命令

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  1. systemctl start docker // 启动docker服务
  2. systemctl stop docker // 停止docker服务
  3. systemctl restart docker // 重启docker服务
  4. systemctl status docker // 查看docker服务状态
  5. systemctl enable docker // 开机启动docker服务
  6. systemctl disable docker // 取消开机启动docker服务

swarm 配置

docker 已内置swarm,无需再手动pull安装

我们有2个服务器作为集群的2个节点,其中,ser1, manager节点,ser2 作为worker节点

初始化集群

语法:

docker swarm init [OPTIONS]

Options:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  1. –advertise-addr: 多网卡的情况下,指定需要使用的ip
  2. –listen-addr: 指定监听的 ip 与端口
  3. –availability: 节点的有效性(“active”|”pause”|”drain”)
  4. Active:集群中该Node可以被指派Task
  5. Pause:集群中该Node不可以被指派新的Task,但是其他已经存在的Task保持运行
  6. Drain:集群中该Node不可以被指派新的Task,Swarm Scheduler停掉已经存在的Task,并将它们调度到可用的Node上

示例

docker swarm init --advertise-addr 192.168.2.101 --listen-addr 192.168.2.101:2377

添加节点

docker swarm join [OPTIONS] HOST:PORT

Options

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  1. –token: 所需加入集群的token
  2. –advertise-addr: 多网卡的情况下,指定需要使用的ip
  3. –listen-addr: 指定监听的 ip 与端口
  4. –availability: 节点的有效性(“active”|”pause”|”drain”)
  5. Active:集群中该Node可以被指派Task
  6. Pause:集群中该Node不可以被指派新的Task,但是其他已经存在的Task保持运行
  7. Drain:集群中该Node不可以被指派新的Task,Swarm Scheduler停掉已经存在的Task,并将它们调度到可用的Node上

添加manager节点

ser1已经是管理节点,这里介绍如何添加另一个管理节点。swarm支持多个管理节点,但是只会有一个leader。

首先要获取manager的token,在ser1上执行以下命令:

docker swarm join-token manager

获取到manager token,然后执行以下命令,将ser2服务器作为manager节点加入集群

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  1. docker swarm join
  2. –advertise-addr 192.168.2.102
  3. –listen-addr 192.168.2.101:2377
  4. –token SWMTKN-1-29ynh5uyfiiospy4fsm4pd4xucyji2rn0oj4b4ak4s7a37syf9-ajkrv2ctjr5cmxzuij75tbrmz
  5. 192.168.2.101:2377

 

worker节点

首先要获取worker的token,在ser1上执行以下命令:

docker swarm join-token worker

获取到worker token,然后执行以下命令,将ser2服务器作为worker节点加入集群:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  1. docker swarm join
  2. –advertise-addr 192.168.2.102
  3. –listen-addr 192.168.2.101:2377
  4. –token SWMTKN-1-29ynh5uyfiiospy4fsm4pd4xucyji2rn0oj4b4ak4s7a37syf9-a53g5oimn8zeaqomm5vxgcoj7
  5. 192.168.2.101:2377

 

查看节点

以下命令只能在manager节点上执行

查出集群的节点列表

语法

docker node ls [OPTIONS]

Options

–filter , -f : 根据条件筛选查询结果

示例

docker node ls

修改节点

以下命令只能在manager节点上执行

节点降级

将manager节点降为worker

语法

docker node demote NODE [NODE...]

示例

docker node demote rpi2

节点升级

将worker节点提升为manager

语法

docker node promote NODE [NODE...]

示例

docker node promote rpi

修改节点参数

语法

docker node update [OPTIONS] NODE

Options

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  1. –availability : 节点的有效性(“active”|”pause”|”drain”)
  2. Active:集群中该Node可以被指派Task
  3. Pause:集群中该Node不可以被指派新的Task,但是其他已经存在的Task保持运行
  4. Drain:集群中该Node不可以被指派新的Task,Swarm Scheduler停掉已经存在的Task,并将它们调度到可用的Node上
  5. –role : 节点角色(“worker”|“manager”)

示例

docker node update --availability Active rpi2

退出节点

docker node rm

从集群中移除一个或多个节点(manager 节点执行)

语法

docker node rm [OPTIONS] NODE [NODE...]

Options

--force , -f : 强制从集群中删除节点

示例

docker node rm -f rpi2

docker swarm leave

退出集群(需要退出的节点执行)

语法

docker swarm leave [OPTIONS]

Options

--force , -f : 强制从集群中删除节点

示例

docker swarm leave

应用部署

创建服务

语法

docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]

Options

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  1. –detach , -d : 指定容器运行于前台还是后台,默认为false
  2. –name : 服务名称
  3. –network : 网络连接
  4. –publish , -p : 端口映射
  5. –env , -e : 设置环境变量
  6. –tty , -t : 分配tty设备,该可以支持终端登录
  7. –mount : 文件挂载
  8. –replicas : 指定任务数量

示例

创建一个docker网络

1
docker network create --driver overlay swarm_test

 

创建一个2个副本的redis service

docker service create --replicas 2 --name redis -p 6379:6379 --network=swarm_test arm32v7/redis

注意:rpi是arm架构的,只能使用arm docker镜像,现在docker官方已经有了arm镜像

arm32v7

arm32v6

修改服务

修改服务参数

语法

docker service update [OPTIONS] SERVICE

Options

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  1. –detach , -d : 指定容器运行于前台还是后台
  2. –env-add : 增加环境变量
  3. –env-rm : 删除环境变量
  4. –mount-add : 增加文件挂载
  5. –mount-rm : 通过目标路径删除文件挂载
  6. –network-add : 增加网络设置
  7. –network-rm : 移除网络设置
  8. –publish-add : 增加端口映射
  9. –publish-rm : 通过目标端口移除端口映射
  10. –replicas : 修改任务数量

 

示例

docker service update --replicas 2 api_131

修改任务数量

虽然通过docker service update命令也可以修改任务数量,但是docker还提供了一个修改任务数量的命令。

该命令可以修改一个或多个服务的任务数量

语法

docker service scale SERVICE=REPLICAS [SERVICE=REPLICAS...]

示例

docker service scale ser1=3 ser2=5

查看服务

查看服务列表

manager节点执行

语法

docker service ls [OPTIONS]

Options

--filter , -f : 过滤条件

示例

docker service ls --filter name=redis

查看任务列表

manager执行,可查看一个或多个服务的任务列表

语法

docker service ps [OPTIONS] SERVICE [SERVICE...]

Options

--filter , -f : 过滤条件

示例

docker service ps redis

查看服务详情

manager执行,可查看一个或多个服务的详细情况

语法

docker service inspect [OPTIONS] SERVICE [SERVICE...]

Options

--pretty : 格式化输出信息

示例

docker service inspect redis

删除服务

manager 执行,删除一个或多个服务

语法

docker service rm SERVICE [SERVICE...]

示例

docker service rm redis

查看服务日志

manager执行,查看服务或任务的日志

语法

docker service logs [OPTIONS] SERVICE|TASK

Options

  1. 1
  2. 2
  3. 3
  4. 4
  1. –follow , -f : 跟随输出
  2. –tail : 显示*新的N条日志
  3. –since : 显示从某个时间开始的所有日志
  4. –timestamps , -t : 显示时间戳

示例

docker service logs -f redis

使用portainer管理docker swarm集群

Portainer是个轻量级的Docker管理面板,和Rancher这种重量级选手没法比,Portainer倾向于单机的管理(后来发现能够添加多个单机节点切换着管理),当然,在Docker搞出Swarm之后Portainer也借此实现了集群管理。

1
docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer:linux-arm-1.17.0

本文使用的portainer镜像为portainer/portainer:linux-arm-1.17.0

 

iOS-关于应用/视图的生命周期及程序启动原理小结

前言:
所有的移动操作系统都有个致命的缺点:app很容易受到打扰。比如一个来电或者锁屏会导致app进入后台甚至被终止

还有很多其它类似的情况会导致app受到干扰,在app受到干扰时,会产生一些系统事件,这时UIApplication会通知它的delegate对象,让delegate代理来处理这些系统事件

delegate可处理的事件包括:

应用程序的生命周期事件(如程序启动和关闭)
系统事件(如来电)
内存警告

应用的生命周期—>启动过程:

应用启动过程

这些UIApplicationDelegate,监听应用程序的生命周期,监听内存警告,系统事件

// 当应用程序启动完毕的时候就会调用 (系统自动调用)

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

NSLog(@”%s”,__func__);

return YES;
}
// 即将失去活动状态的时候调用(失去焦点, 不可交互)

– (void)applicationWillResignActive:(UIApplication *)application {

NSLog(@”%s”,__func__);

}
// 应用程序即将进入前台的时候调用
// 一般在该方法中恢复应用程序的数据,以及状态

– (void)applicationWillEnterForeground:(UIApplication *)application {

NSLog(@”%s”,__func__);

}
// 应用程序进入后台的时候调用
// 一般在该方法中保存应用程序的数据, 以及状态
– (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(@”Background”);
}
// 重新获取焦点(能够和用户交互)

– (void)applicationDidBecomeActive:(UIApplication *)application {

NSLog(@”%s”,__func__);

}
// 应用程序即将被销毁的时候会调用该方法
// 注意:如果应用程序处于挂起状态的时候无法调用该方法

– (void)applicationWillTerminate:(UIApplication *)application {

}
// 应用程序接收到内存警告的时候就会调用
// 一般在该方法中释放掉不需要的内存

– (void)applicationDidReceiveMemoryWarning:(UIApplication *)application

{

NSLog(@”%s”,__func__);

}
应用程序一般有五个状态:官方文档app.states

程序启动生命周期:–> (启动过程)
A篇:启动原理
① 执行main 函数,调用 main 函数里的 UIApplicationMain 函数。

intUIApplicationMain(int argc, char argv[], NSString principalClassName, NSString *delegateClassName);

argc、argv:直接传递给UIApplicationMain进行相关处理即可
principalClassName:指定应用程序类名(app的象征),该类必须是UIApplication(或子类)。如果为nil,则用UIApplication类作为默认值
delegateClassName:指定应用程序的代理类,该类必须遵守UIApplicationDelegate协议
② UIApplicationMain函数会根据principalClassName创建UIApplication对象,根据delegateClassName创建一个delegate对象,并将该delegate对象赋值给UIApplication对象中的delegate属性

③ 接着会建立应用程序的Main Runloop(事件循环),进行事件的处理(首先会在程序完毕后调用delegate对象的application:didFinishLaunchingWithOptions:方法)

④ 程序正常退出时UIApplicationMain函数才返回

系统入口的代码和参数说明:

argc:系统或者用户传入的参数
argv:系统或用户传入的实际参数

1.根据传入的第三个参数,创建UIApplication对象
2.根据传入的第四个产生创建UIApplication对象的代理
3.设置刚刚创建出来的代理对象为UIApplication的代理
4.开启一个事件循环(可以理解为里面是一个死循环)这个时间循环是一个队列(先进先出)先添加进去的先处理

B篇:(完整启动过程)

1.执行main 函数,调用 main 函数里的 UIApplicationMain 函数。

2.创建UIApplication
① 打开网页,发短信,打电话
② 设置应用程序提醒数字
③ 设置联网状态
④ 设置状态栏

3.创建AppDelegate代理对象,并且成为AppDelegate代理
① 监听整个App的生命周期
② 处理内存警告

4.开启主运循环,保证程序一直运行
① 每一个线程都有runloop
② 主线程有一个runloop

5.加载info.plist (判断是否加载了main.storyboard)

情况1:–> 如果指定(没有storyboard)
就会在application:didFinishLaunchingWithOptions:中
① 创建窗口
② 设置根控制器
③ 显示窗口

情况2:–> 如果加载的Info.plist文件里的Main storyboard:
系统会自动调用 (不用我们管)
① 创建窗口
② 加载main.storyboard,并且加载main.storyboard指定的控制器
③ 把新创建的控制器,作为窗口的根控制器,让窗口显示出来

如图:

程序启动过程
视图的生命周期—>view:

视图的生命周期
1、 alloc 创建对象,分配空间
2、 init (initWithNibName) 初始化对象,初始化数据
3、 loadView 从nib载入视图 ,除非你没有使用xib文件创建视图
4、 viewDidLoad 载入完成,可以进行自定义数据以及动态创建其他控件
5、 viewWillAppear视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了
6、 viewDidAppear 视图已在屏幕上渲染完成
7、viewWillDisappear 视图将被从屏幕上移除之前执行
8、viewDidDisappear 视图已经被从屏幕上移除,用户看不到这个视图了
9、dealloc 视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放.
10、viewVillUnload- 当内存过低,即将释放时调用;
11、viewDidUnload-当内存过低,释放一些不需要的视图时调用。

arthas动态修改 LOGGER 级别

前言

大多数情况下,我们会在打印日志时定义日志的LOGGER级别,用来控制输出的信息范围。

一方面,过多的输出会影响查看日志的效率,另一方面,过少的日志让问题定位变得困难。

但当线上出现问题时,线上容器通常定义在info级别,发生一些疑难问题时,光靠info级别的日志很难定位问题。

一个典型的场景:在一些需要打印MySQL语句的场景,如果你正在使用MyBatis框架,由于MyBaits中SQL语句是DEBUG级别的信息,通常在线上容器就没法看到。

一个丑陋的解决办法就是在沙箱/预发环境,将log4j.xml中的info改为debug:

 

 

 

<Root level=”info”>

<AppenderRef ref=”detail”/>

<AppenderRef level=”error” ref=”error”/>

</Root>

 

 

 

 

然后重新打包部署,再发起请求来调试代码。

甚至在一些无法模拟请求的场景下,还需要将修改灰度至线上环境,大量的debug信息会对线上服务造成实质性的影响。

「本文简要介绍如何使用阿里巴巴开源Java调试工具Arthas,实时修改线上服务的LOGGER级别,从而免去打包再部署的繁杂手续,更快的定位线上问题。」

「效果演示:」

 

%title插图%num

 

本地测试:实时修改LOGGER级别

安装arthas

网络安装

在接通外网的环境下,可以使用快速网络安装,会从阿里的源拉去全量包。

 

 

 

curl -O https://arthas.aliyun.com/arthas-boot.jar

java -jar arthas-boot.jar

 

 

 

 

全量安装

如果本地外网环境不通,比如某些容器内是不允许外网访问的,那么可以使用预先下载好的全量安装包,然后解压后运行包内的jar,使用命令:

 

 

 

java -jar arthas-boot.jar

 

 

 

 

启动arthas

我在本地启动arthas,效果如下图:

 

%title插图%num

 

全局Logger信息

使用命令:

 

 

 

logger

 

 

 

 

 

%title插图%num

 

可以看到所有logger的信息,包括其中每个appenders。

使用如下命令,修改名称为ROOT的logger的日志级别至debug级别:

 

 

 

logger –name ROOT –level debug

 

 

 

 

 

%title插图%num

 

可以看到多出了debug级别的输出。

指定类名的logger信息

在有多个logger的情况下,可以查找指定名称的logger

 

 

 

logger -n ROOT

 

 

 

 

 

%title插图%num

 

指定classloader的logger信息

如果需要改变指定类的输出级别,先要定位到该类的classLoader,然后修改该clasLoader的logger。

使用sc命令查看你需要改变的类信息:

 

 

 

sc -d cn.monitor4all.miaoshaweb.DynamicLoggerTest | grep classLoaderHash

 

 

 

 

 

%title插图%num

 

随后可以通过classLoader找到其对应的logger:

 

 

 

logger -c 18b4aac2

 

 

 

 

 

%title插图%num

 

然后就可以调整对应的logger日志级别:

 

 

 

logger -c 18b4aac2 –name ROOT –level debug

 

 

 

 

 

%title插图%num

 

%title插图%num

 

使用 ongl 命令

此外,Arthas还支持使用ognl来修改日志级别。但是这种方法对log4j不友好,修改会报错。并且就算支持的logback/slf4j,也需要复杂的形如ognl -c @org.slf4j.LoggerFactory@getLogger(“root”).setLevel()的命令才能修改,并不是一个很好的办法。

线上实战:实时打印MyBatis SQL语句

容器内启动arthas

我的线上容器,是没有外网访问权限的(这种情况蛮常见的),我将全量包解压在容器内运行:

 

%title插图%num

 

打印DEBUG级别的SQL日志

下图是没有DEBUG信息的一条请求日志,可以看到只有入参出参的拦截器信息(INFO级别):

 

%title插图%num

 

使用logger --name ROOT --level debug,将SQL语句输出出来:

 

%title插图%num

 

毕竟,很多时候线上的bug是不小心拼错SQL导致。

总结

文章简单总结了使用Arthas来动态调整日志级别的使用方法。在线上环境,能够有效的提升排查问题的效率。当然Arthas能做的还远不止于此,更多有趣并且「实用」的功能等待大家的发掘。

使用Arthas 获取Spring ApplicationContext还原问题现场

背景

*近来了个实习僧小弟,安排他实现对目标网站 连通性检测的小功能,简单讲就是将下边的shell 脚本换成Java 代码来实现

  1. 1#!/bin/bash
  2. 2URL=“https://www.baidu”
  3. 3HTTP_CODE=`curl -o /dev/null -s -w “%{http_code}” “${URL}”`
  4. 4#echo $HTTP_CODE
  5. 5if [ $HTTP_CODE != ’200′ ];then
  6. 6curl ‘https://oapi.dingtalk.com/robot/send?access_token=xx’ \
  7. 7H ‘ContentType: application/json’ \
  8. 8 -d ‘{“msgtype”: “text”,
  9. 9 “text”: {
  10. 10 “content”: “百度平台状态不正常,请注意!”
  11. 11 },
  12. 12 “isAtAll”: true
  13. 13 }’
  14. 14
  15. 15fi

功能实现

使用spring task

  1. 1@Scheduled(cron = “0 0 0/1 * * ? “)
  2. 2public void startSchedule() {
  3. 3 log.info(“开始执行定时任务 ,检测百度网站连通性”);
  4. 4 try {
  5. 5 HttpResponse response = HttpRequest.get(“”).execute();
  6. 6 if (HttpStatus.HTTP_OK != response.getStatus()) {
  7. 7 this.send2DingTalk(response.getStatus());
  8. 8 }
  9. 9 log.info(“请求百度成功,返回报文:{}”,response.body());
  10. 10 } catch (HttpException e) {
  11. 11 log.error(“请求异常百度:{}”, e);
  12. 12 this.send2DingTalk(e.getMessage());
  13. 13 }
  14. 14 log.info(“执行检测百度网站连通任务完毕”);
  15. 15}

问题描述

部署在服务器上,我的老jio本 都已经呼叫任务状态不正常了,可是小弟的Java 代码还是没有执行通知

 

%title插图%num

 

  • 去翻生产日志,只输入了开始并没有输出定时任务结束,感觉是哪里卡死,想当然以为如果超时总会到catch 逻辑,排查无果
  • 由于任务是一小时一次,如何快速触发一下这个异常,还原事故现场
  • 由于使用简单的Spring Task 没有图形化界面和API接口

Arthas 还原事故现场,重新触发任务

核心拿到 spring context 然后执行它的 startSchedule 方法

确定监控点

  • SpringMVC 的请求会通过 RequestMappingHandlerAdapter 执行invokeHandlerMethod 到达目标接口上进行处理
  • 而在 RequestMappingHandlerAdapter类中有 getApplicationContext()
  1. 1@Nullable
  2. 2public final ApplicationContext getApplicationContext() throws IllegalStateException {
  3. 3 if (this.applicationContext == null && this.isContextRequired()) {
  4. 4 throw new IllegalStateException(“ApplicationObjectSupport instance [“ + this + “] does not run in an ApplicationContext”);
  5. 5 } else {
  6. 6 return this.applicationContext;
  7. 7 }
  8. 8}
  • 任意执行一次请求获取到 RequestMappingHandlerAdaptertarget 目标,然后执行 getApplicationContext

tt命令 获取到ApplicationContext

  • arthas 执行 tt
1tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
  • 任意执行一次web 请求,tt 即可捕获

%title插图%num

 

  • 根据目标的索引,执行自定义 OGNL 表达式即可
1tt -i 1019 -w 'target.getApplicationContext()'

 

%title插图%num

 

使用ApplicationContext获取 定时任务bean 执行 startSchedule

1tt -i 1000 -w 'target.getApplicationContext().getBean("baiduSchedule").startSchedule()'

ok 任务重新触发了

事故原因调查清楚,由于使用hutool 的工具类 没有设置timeout 导致无限等待,所以没有执行catch 逻辑

总结

以上吓哭实习僧的操作禁止生产操作,只是提供个思路 ,当然可以衍生其他业务场景的操作

核心是通过Arthas 来抓取Spring ApplicationContext 对象,然后获取bean 进行执行方法

关于Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱

你不理解的“OLAP”,从这4点一看就可以明白

但凡从事数据相关工作的人,都多多少少听说过“OLAP”。但大部分还是处于懵懵懂懂的状态,只知道是一种数据分析技术的统称。那么,OLAP到底是什么?它和BI有什么关系?今天小麦就和大家一起一探究竟。

 

ONE 什么OLAP?

OLAP的概念*早是由关系数据库之父E.F.Codd于1993年提出的,他同时提出了关于OLAP的12条准则。OLAP的提出引起了很大的反响,OLAP作为一类产品同联机事务处理 (OLTP) 明显区分开来。

当今的数据处理大致可以分成两大类:联机事务处理OLTP(On-Line Transaction Processing)、联机分析处理OLAP(On-Line Analytical Processing)。OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易;OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。OLAP使用户能够从多角度对信息进行快速、一致、交互地存取,从而获得对数据更深入了解的一类软件技术。OLAP的目标是满足决策支持或者满足在多维环境下特定的查询和报表需求,它的技术核心是”维”这个概念。

“维”是人们观察客观世界的角度,是一种高层次的类型划分。“维”一般包含着层次关系,这种层次关系有时会相当复杂。通过把一个实体的多项重要的属性定义为多个维(Dimension),使用户能对不同维上的数据进行比较。因此OLAP也可以说是多维数据分析工具的集合。

 

TWO OLAP的操作

OLAP的基本多维分析操作有钻取(Roll Up和Drill Down)、切片(Slice)和切块(Dice)、以及旋转(Pivot)、Drill Across、Drill Through等。

「技术干货」你不理解的“OLAP”,从这4点一看就可以明白

 

钻取是改变维的层次,变换分析的粒度。它包括向上钻取(Roll Up)和向下钻取(Drill Down)。Roll Up是在某一维上将低层次的细节数据概括到高层次的汇总数据,或者减少维数;而Drill Down则相反,它从汇总数据深入到细节数据进行观察或增加新维。

「技术干货」你不理解的“OLAP”,从这4点一看就可以明白

 

切片和切块是在一部分维上选定值后,关心度量数据在剩余维上的分布。如果剩余的维只有两个,则是切片;如果有三个,则是切块。

「技术干货」你不理解的“OLAP”,从这4点一看就可以明白

 

旋转是变换维的方向,即在表格中重新安排维的放置(例如行列互换)。

「技术干货」你不理解的“OLAP”,从这4点一看就可以明白

 

OLAP是针对特定问题的联机数据,通过多维的方式进行查询与分析。维是人们观察数据的特定角度。例如,一个企业在考虑产品的销售情况时,通常从时间、地区和产品的不同角度来深入观察产品的销售情况。这里的时间、地区和产品就是维,而这些维的不同组合和所考察的度量指标构成的多维数组则是OLAP分析的基础。

多维分析是指对以多维形式组织起来的数据采取切片(Slice)、切块(Dice)、钻取(Drill Down和Roll Up)、旋转(Pivot)等各种分析动作,以求剖析数据,使用户能从多个角度、多侧面地观察数据库中的数据,从而深入理解包含在数据中的信息。

 

THREE OLAP的分类

OLAP按存储器的数据存储格式分为ROLAP、MOLAP和HOLAP。

MOLAP(Multi-dimensional OLAP)以多维数组模型存储数据,它的特点是数据需要预计算(pre-computaion),然后把预计算之后的结果(cube)存在多维数组里。因为cube包含所有维度的聚合结果,所以查询速度非常快。但查询灵活度比较低,需要提前设计维度模型,查询分析的内容仅限于这些指定维度,增加维度需要重新计算。

ROLAP(Relational OLAP)以关系模型存储数据,一般要求事实表(fact table)和维度表(dimensition table)按一定关系设计,它不需要预计算,使用标准SQL就可以根据需要即时查询不同维度数据。它的扩展性强,适用于维度数量多的模型。但因为是即时计算,查询响应时间一般比预计算的MOLAP长。

不管是MOLAP的多维数据模型,还是ROLAP的关系模型,它们都需要预先设计好模型后才可以使用。

 

FOUR OLAP与BI的关系

BI包括数据采集、数据准备、数据分析和数据共享等环节,数据分析又包括报表、OLAP、数据挖掘、数据可视化等多种分析技术。所以说,OLAP只是BI的一部分,是BI中一种数据分析技术。因为OLAP需要预先建模,所以在BI中主要是用于“描述发生了什么?”,它和报表、仪表盘一样,是属于“静态”的一种分析技术,用于构建信息门户或监控数据。

透视分析是*常用的一款OLAP分析工具,可以快速分类汇总、比较大量的数据,并且可以根据用户的业务需求,快速变换统计分析维度来查看统计结果。透视分析不仅综合了数据排序、筛选、组合及分类汇总等数据分析方法的优点,而且汇总的方式更灵活多变,并能以不同方式显现数据。

但是,基于OLAP的透视分析需要复杂的数据加工过程,需要cube,需要建立维度表、事实表、定维度层次、聚合指标等等,数据查询需要写SQL语句。

所以,我们需要对“静态”的透视分析进行改良,让它成为“动态”的一种分析工具,让用户可以对数据进行自由地探索。让它不仅能够“描述发生了什么?”,而且还能够“分析为什么会发生?”。

例如,Smartbi的透视分析工具采用“类Excel数据透视表”的设计,多维分析不再需要建立模型,就能够组合维度、汇总计算、切片、钻取,洞察数据。不仅如此,任何字段都可直接作为输出字段或筛选条件,轻松实现对数据的查询与探索。

「技术干货」你不理解的“OLAP”,从这4点一看就可以明白

 

Smartbi在后续的V10版本中,还会对数据集进行重构,在数据集中集成全新的OLAP引擎,把OLAP分析能力赋予报表、仪表盘、透视分析等多种分析工具,打造一个更加智能化的大数据分析平台。

综上所述,OLAP的作用就是让用户可以快速地从不同的角度洞察数据的情况。在数据量大且维度指标众多的情况下,可以让用户聚焦分析的重点。说到这里,大家对“OLAP”的理解是不是深刻很多了呢?

对数据湖概念及其应用场景若干问题的思考

在大数据平台后可以看到有两个衍生出来的概念词相当的火热,一个是数据中台,还有一个就是数据湖,今天准备谈下对这方面的一些思考。

从数据湖的基本概念说起

对数据湖概念及其应用场景若干问题的思考

 

首先看下维基百科上的定义如下:

数据湖(Data Lake)是一个以原始格式存储数据的存储系统。它按原样存储数据,而无需事先对数据进行结构化处理。一个数据湖可以存储结构化数据(如关系型数据库中的表),半结构化数据(如CSV、日志、XML、JSON),非结构化数据(如电子邮件、文档、PDF)和二进制数据(如图形、音频、视频)。

而在百度百科上的定义如下:

数据湖或hub的概念*初是由大数据厂商提出的,表面上看,数据都是承载在基于可向外扩展的HDFS廉价存储硬件之上的。但数据量越大,越需要各种不同种类的存储。*终,所有的企业数据都可以被认为是大数据,但并不是所有的企业数据都是适合存放在廉价的HDFS集群之上的。

如果综合这两个定义,可以看到数据湖的核心即是:存储各种类型数据的大型可扩展的存储库。这里面实际体现了两个重点,其一就是结构化,非结构化,关系表或视频图片等都可以进行原始格式存储,其次就是这个存储是分布式可无限水平扩展的。

当看到这里的时候,相信大家都会想到,这个和日常谈到的大数据平台里面的类似HDFS的分布式存储不是一个意思吗,为何又要去发明一个数据湖的概念。

在谈这个之前,先回到大数据平台这个概念。

对数据湖概念及其应用场景若干问题的思考

 

当我们在谈大数据平台的时候,更容易将其理解为一个技术平台。比如对于大数据平台常见的定义如下:大数据平台是对海量结构化、非结构化、半机构化数据进行采集、存储、计算、统计、分析处理的一系列技术平台。

因此大数据平台的关注点在技术平台上,而非在数据上面。而当谈数据湖的时候,可以看到这个时候的关注点是在数据上,而不是具体的实现技术或平台上。数据湖的底层技术支撑可以是类似Hadoop的大数据平台,也可以是其它,比如类似亚马逊的S3对象存储为核心支撑能力并进行扩展。

其次,数据中台这个概念*近几年也相当活,在原来谈数据中台的时候谈得比较多的是共性数据服务能力的共享和开放。而谈到数据中台的时候刚好同时体现了数据+平台两个方面的关键特性。

简单来说就是既要关注底层平台建设,又要关注*终的数据资产和能力。

数据湖参考架构

对数据湖概念及其应用场景若干问题的思考

 

在这里不准备详细去谈数据湖的参考架构和具体功能点,因为当你去分析详细的架构模块和功能的时候,发现仍然是类似数据采集,数据集成,数据存储,数据管控治理,数据接口开放等功能,这个和实际你谈数据中台架构,大数据平台,包括传统的BI系统的时候功能都差不多。

数据湖的核心是多样化数据的可扩展存储。基于这个核心实际上可以将数据湖核心功能理解为如下三个方面的内容。

数据流入:包括了数据的采集,数据的集成

数据存储:包括各类结构化,非结构化数据的可扩展弹性存储

数据流出:需要提供标准统一的API接口或统一的SQL层等开放数据能力

这三个方面可以理解为数据湖的核心能力,其它的类似数据清洗转化,数据治理,数据质量管理等都是扩展能力,不是数据湖的核心。同时我个人实际是比较反对将这些能力全部加到数据湖参考架构里面的,一个重要的原因就是数据湖会构建得越来越重,而脱离了提出数据湖这个概念的初衷。

数据湖概念的提出和扩展

对数据湖概念及其应用场景若干问题的思考

 

这个术语由Pentaho公司的创始人兼首席技术官詹姆斯·狄克逊(James Dixon)发明,他对数据湖的解释是: 把你以前在磁带上拥有的东西倒入到数据湖,然后开始探索这些数据。当时Pentaho公司刚发布了基于Hadoop的BI分析软件,推出这些概念更多的是为了自身产品和市场营销。

而*近几年这个概念却是以亚马逊为首的各大公有云服务厂商。亚马逊AWS对数据湖做了进一步解释,即:

数据湖是一个集中式存储库,允许您以任意规模存储所有结构化和非结构化数据。您可以按原样存储数据(无需先对数据进行结构化处理),并运行不同类型的分析 – 从控制面板和可视化到大数据处理、实时分析和机器学习,以指导做出更好的决策。”

简单来说公有云服务厂商希望企业本身的大数据存储,数据分析等业务也全部迁移到公有云服务上。类似亚马逊以S3为核心并扩展的数据湖相关服务和产品。国内的阿里云基于HDFS扩展的数据湖产品服务等。

为何公有云厂商如此重视这块?

对数据湖概念及其应用场景若干问题的思考

 

拿传统企业IT建设和信息化来举例大家很容易明白。一般企业的IT规划建设都是先建设了底层的IT基础设施,然后构建了满足企业各类业务运作的IT系统,其次才是构建了类似BI商业智能等相关分析类系统,从OLTP走向OLAP分析。

对于公有云服务厂商来说,从*早的仅仅提供IaaS资源层服务能力,到随着云原生技术的推进,逐步开始提供完整的PaaS层应用和服务托管能力。企业内部的IT系统完全基于云平台提供的服务能力进行构建和持续集成交付。

那么企业IT在交付到云端,并持续运行后,一定存在多个业务系统间的数据整合和集成,大数据分析等场景。这个时候公有云就需要提供配套的大数据分析类平台和服务。这种服务的核心除了基础的大数据技术平台外,更加重要的是提供一套完整的数据采集集成,数据存储,数据开放的能力。

当企业的IT系统全部上云后,数据存储全部在云上,这个时候不可能说还需要把数据采集和集成回到企业内部数据中心在进行数据整合和分析。那么云端提供传统大数据分析或BI分析的能力就是必须配套的一个能力。

从这个意思上来说,数据湖和数据分析能力提供就是必须的。

一个企业如果所有的IT系统都还在自己的私有数据中心里面,这个时候会不会把所有的数据采集同步到公有云提供提供的数据湖服务,并进行数据分析?

这个场景当然也存在,但是实际上更多的仅仅是数据扩展存储和存储后的标准接口开放。如果这些数据真要用到数据分析,往往很难。这个涉及到私有云端和公有云端的大量接口协同问题,并没有那么容易解决。

数据湖,数据中台,大数据平台和数据仓库

数据湖和数据中台

数据中台包括了底层数据技术平台(可以是我们熟悉的大数据平台能力),中间的数据资产层,上层的数据对外能力开放。核心的资产层本身也分层,从*底层的贴源数据,到分域应用数据,再到上层的数据仓库和数据标签库。而数据湖更多对应到数据中台概念里面的数据贴源层。

数据湖和数据中台映射如下:

对数据湖概念及其应用场景若干问题的思考

 

简单来说就是数据中台在数据资产层比数据湖重得多,数据湖建议是仅仅是原始数据存储,而不应该是大量的数据清洗加工,数据模型,数据分析算法。包括复杂的数据质量管理,数据管控治理等都应该弱化。

数据湖和大数据平台

对于数据湖和大数据平台,实际更多的只是侧重点不同,一个侧重于数据,一个侧重于技术平台。当然对于大数据平台本身提供了数据湖建设的核心技术底座。

在前面已经谈到数据湖核心还是数据存储和接口开放,因此可以看到对于完整的大数据平台构建内容实际上进行了分层解耦。

即数据存储和能力开放与后续的数据处理和数据分析解耦。解耦后你可以看到数据湖提供的能力既可以用于传统的BI,大数据分析,也可以应用到直接提供数据服务能力给业务系统协同使用。

数据湖和数据仓库

对数据湖概念及其应用场景若干问题的思考

 

对于这两个概念的比较,网上更多在强调数据湖可以存储结构化,非结构化各类数据,而传统的数据仓库仅仅是存储和处理分析结构化数据。

但实际在这里个人更强调数据湖仅仅是数据仓库的底座,而不应该具备类似数据仓库有的复杂数据建模,数据清洗转换,数据分析等能力。

也就是说经过加工和聚合后的数据可以放在独立的数据分析类应用中,但是当需要查看详细的数据明细的时候,这直接调用数据湖接口访问数据湖里面的数据资源。

传统的数据仓库和BI系统建设是一个很复杂的事情,类似数据建模,数据质量管理,数据治理,数据可视化等很多内容本身不属于数据湖的范畴。

传统企业是否有必要搞数据湖?

对数据湖概念及其应用场景若干问题的思考

 

首先表明个人观点,数据湖更多的是当前头部的公有云服务厂商在玩的事情,对于传统企业来说完全没有必要搞数据湖,包括大数据平台都没有必要。

为何这样说?

简单来说一般的企业本身遇到的数据类型,数据量等问题,用传统的BI方法就已经可以很好地解决,即使传统BI无法扩展,还有类似MPP等方式来解决。这种方式本身是*容易实施,也是见效*快的方式。

而对于数据湖或者大数据平台来讲,本身会引入更多的技术复杂性,包括前期的投入成本。而唯一的好处就是可以满足企业5到10年,甚至更长时间的业务发展,资源弹性扩展需求。为了这种扩展性去引入这种技术复杂性和成本投入对于大部分企业来说都不值得。

在前面我就谈到过。

当你为了满足扩展性和性能等需求的时候,整个IT技术架构的复杂性会越来越大,在这种情况下往往后续整个IT治理管控的复杂性,平台运维的复杂性,功能开发和交付的复杂性都显著增加。这种复杂性不是一般的企业能够扛得住的。

在谈数据湖的底层数据存储的时候,实际我一直有一个疑惑。即按照理想的做法是,各类数据采集和集成后,都通过标准的方式进行存储和能力提供,类似亚马逊的S3对象存储。即使是结构化的数据,*终也存储到S3分布式对象存储中。

在这种场景下,你就需要提供更换的类似传统SQL查询的接口能力,否则数据存储下去是方便了,但是使用却变得更加复杂的。如果你是用的S3存储或HDFS存储,简单来说要完整的提供完整的数据服务能力往往变得更加困难。比如常说的虽然OLAP能力增强了,但是OLTP方面能力,数据实时查询或处理的能力却变弱了。

在类似华为的解决方案里面,实际看到仍然采用了传统的结构化数据库来存储结构化数据,这个实际才是短期更加可行的方案。数据库的数据存储可以采用结构化数据库,MPP库,HDFS等多种存储方式,虽然底层数据存储有差异,但是可以提供一个统一的数据服务能力开放层来解决问题。

那么企业本身的数据孤岛问题如何解决,特别是在微服务架构化后引入的数据孤岛问题。实际上这个我在很早文章就提到,企业更需要的是一个分布式的共享ODS存储库。

对数据湖概念及其应用场景若干问题的思考

 

为何通过共享ODS库来提供数据服务能力,而不是由原来的业务系统或单个微服务模块来提供数据服务能力。这里面有一个重点就是对于数据服务而言往往需要提供领域数据服务能力,涉及到底层多种数据库表的关联查询动作。而在传统方式下,这个往往涉及到跨库查询才能够实现,也就是说单个业务系统往往并没有能力提供。

这也是为何在传统模式下,会考虑再规划建设一个独立的领域服务层微服务模块,来专门处理这类服务。即使这样处理也存在要多次调用后台数据库接口,然后在逻辑层进行组合和组装的问题,那么在性能上肯定会造成一定的损耗。

而共享ODS库要做的就是将共享的基础主数据和各个业务系统中共享的动态数据(类似项目,订单,合同)等全部进行集中,集中到ODS库来提供统一的共享数据服务能力。那么原来上层应用需要调用各个业务系统或模块提供的数据服务来获取数据,而新架构下只需要通过共享数据中心ODS库提供的共享数据服务来查询数据即可。

超级干货:3个性能监控和优化命令详解

小编为大家整理出了三个有关性能监控和优化命令详细讲解,别看只有三个,但不影响他噎啊,本篇文章很长,涉及top命令、free命令和vmstat命令,真的是很详细的讲解,希望能帮到大家,另外还有两条相关的命令详解,消化消化这篇的知识,过几天再上那两条~

 

1 top命令

top 命令是 Linux 下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于 Windows 的任务管理器。

下面详细介绍它的使用方法。top 是一个动态显示过程,即可以通过用户按键来不断刷新当前状态。如果在前台执行该命令,它将独占前台,直到用户终止该程序为止。

比较准确的说,top 命令提供了实时的对系统处理器的状态监视。它将显示系统中 CPU*“敏感”的任务列表。该命令可以按 CPU 使用。

内存使用和执行时间对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定。

命令格式:

top [参数]

命令功能:

显示当前系统正在执行的进程的相关信息,包括进程ID、内存占用率、CPU占用率等

命令参数:

  • -b 批处理
  • -c 显示完整的治命令
  • -I 忽略失效过程
  • -s 保密模式
  • -S 累积模式
  • -i<时间> 设置间隔时间
  • -u<用户名> 指定用户名
  • -p<进程号> 指定进程
  • -n<次数> 循环显示的次数

4.使用实例:

实例1:显示进程信息

命令:top

输出:

[root@TG1704 log]# toptop - 14:06:23 up 70 days, 16:44, 2 users, load average: 1.25, 1.32, 1.35Tasks: 206 total, 1 running, 205 sleeping, 0 stopped, 0 zombieCpu(s): 5.9%us, 3.4%sy, 0.0%ni, 90.4%id, 0.0%wa, 0.0%hi, 0.2%si, 0.0%stMem: 32949016k total, 14411180k used, 18537836k free, 169884k buffersSwap: 32764556k total, 0k used, 32764556k free, 3612636k cached  PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 28894 root 22 0 1501m 405m 10m S 52.2 1.3 2534:16 java 18249 root 18 0 3201m 1.9g 11m S 35.9 6.0 569:39.41 java  2808 root 25 0 3333m 1.0g 11m S 24.3 3.1 526:51.85 java 25668 root 23 0 3180m 704m 11m S 14.0 2.2 360:44.53 java  574 root 25 0 3168m 611m 10m S 12.6 1.9 556:59.63 java  1599 root 20 0 3237m 1.9g 11m S 12.3 6.2 262:01.14 java  1008 root 21 0 3147m 842m 10m S 0.3 2.6 4:31.08 java 13823 root 23 0 3031m 2.1g 10m S 0.3 6.8 176:57.34 java 28218 root 15 0 12760 1168 808 R 0.3 0.0 0:01.43 top 29062 root 20 0 1241m 227m 10m S 0.3 0.7 2:07.32 java  1 root 15 0 10368 684 572 S 0.0 0.0 1:30.85 init  2 root RT -5 0 0 0 S 0.0 0.0 0:01.01 migration/0  3 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0  4 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/0  5 root RT -5 0 0 0 S 0.0 0.0 0:00.80 migration/1  6 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/1  7 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/1  8 root RT -5 0 0 0 S 0.0 0.0 0:20.59 migration/2  9 root 34 19 0 0 0 S 0.0 0.0 0:00.09 ksoftirqd/2  10 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/2  11 root RT -5 0 0 0 S 0.0 0.0 0:23.66 migration/3  12 root 34 19 0 0 0 S 0.0 0.0 0:00.03 ksoftirqd/3  13 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/3  14 root RT -5 0 0 0 S 0.0 0.0 0:20.29 migration/4  15 root 34 19 0 0 0 S 0.0 0.0 0:00.07 ksoftirqd/4  16 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/4  17 root RT -5 0 0 0 S 0.0 0.0 0:23.07 migration/5  18 root 34 19 0 0 0 S 0.0 0.0 0:00.07 ksoftirqd/5  19 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/5  20 root RT -5 0 0 0 S 0.0 0.0 0:17.16 migration/6  21 root 34 19 0 0 0 S 0.0 0.0 0:00.05 ksoftirqd/6  22 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/6  23 root RT -5 0 0 0 S 0.0 0.0 0:58.28 migration/7

说明:

统计信息区:前五行是当前系统情况整体的统计信息区。下面我们看每一行信息的具体意义。

*行,任务队列信息,同 uptime 命令的执行结果,具体参数说明情况如下:

  • 14:06:23:当前系统时间
  • up 70 days, 16:44:系统已经运行了70天16小时44分钟(在这期间系统没有重启过的吆!)
  • 2 users:当前有2个用户登录系统
  • load average: 1.15, 1.42, 1.44:load average 后面的三个数分别是1分钟、5分钟、15分钟的负载情况。
  • load average 数据是每隔 5 秒钟检查一次活跃的进程数,然后按特定算法计算出的数值。如果这个数除以逻辑 CPU 的数量,结果高于5的时候就表明系统在超负荷运转了。

第二行,Tasks — 任务(进程),具体信息说明如下:

系统现在共有 206 个进程,其中处于运行中的有1个,205 个在休眠(sleep),stoped状态的有0个,zombie 状态(僵尸)的有0个。

第三行,cpu状态信息,具体属性说明如下:

  • 5.9%us:用户空间占用CPU的百分比。
  • 3.4% sy:内核空间占用CPU的百分比。
  • 0.0% ni:改变过优先级的进程占用CPU的百分比
  • 90.4% id:空闲CPU百分比
  • 0.0% wa:IO等待占用CPU的百分比
  • 0.0% hi:硬中断(Hardware IRQ)占用CPU的百分比
  • 0.2% si:软中断(Software Interrupts)占用CPU的百分比

备注:在这里CPU的使用比率和windows概念不同,需要理解linux系统用户空间和内核空间的相关知识!

第四行,内存状态,具体信息如下:

  • 32949016k total — 物理内存总量(32GB)
  • 14411180k used — 使用中的内存总量(14GB)
  • 18537836k free — 空闲内存总量(18GB)
  • 169884k buffers — 缓存的内存量 (169M)

第五行,swap交换分区信息,具体信息说明如下:

  • 32764556k total — 交换区总量(32GB)
  • 0k used — 使用的交换区总量(0K)
  • 32764556k free — 空闲交换区总量(32GB)
  • 3612636k cached — 缓冲的交换区总量(3.6GB)

备注:

第四行中使用中的内存总量(used)指的是现在系统内核控制的内存数,空闲内存总量(free)是内核还未纳入其管控范围的数量。纳入内核管理的内存不见得都在使用中,还包括过去使用过的现在可以被重复利用的内存,内核并不把这些可被重新使用的内存交还到free中去,因此在linux上free内存会越来越少,但不用为此担心。

如果出于习惯去计算可用内存数,这里有个近似的计算公式:第四行的free + 第四行的buffers + 第五行的 cached,按这个公式此台服务器的可用内存:18537836k +169884k +3612636k = 22GB左右。

对于内存监控,在 top 里我们要时刻监控第五行 swap 交换分区的used,如果这个数值在不断的变化,说明内核在不断进行内存和swap的数据交换,这是真正的内存不够用了。

第六行,空行。

第七行以下:各进程(任务)的状态监控,项目列信息说明如下:

  • PID:进程id
  • USER:进程所有者
  • PR:进程优先级
  • NI:nice值。负值表示高优先级,正值表示低优先级
  • VIRT:进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
  • RES:进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
  • SHR:共享内存大小,单位kb
  • S:进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
  • %CPU:上次更新到现在的CPU时间占用百分比
  • %MEM:进程使用的物理内存百分比
  • TIME+:进程使用的CPU时间总计,单位1/100秒
  • COMMAND:进程名称(命令名/命令行)

其他使用技巧:

1.多U多核CPU监控

在top基本视图中,按键盘数字“1”,可监控每个逻辑CPU的状况:

超级干货:3个性能监控和优化命令详解

观察上图,服务器有16个逻辑CPU,实际上是4个物理CPU。再按数字键1,就会返回到top基本视图界面。

2.高亮显示当前运行进程

敲击键盘“b”(打开/关闭加亮效果),top的视图变化如下:

超级干货:3个性能监控和优化命令详解

我们发现进程id为2570的“top”进程被加亮了,top进程就是视图第二行显示的唯一的运行态(runing)的那个进程,可以通过敲击“y”键关闭或打开运行态进程的加亮效果。

3.进程字段排序

默认进入top时,各进程是按照CPU的占用量来排序的,在下图中进程ID为28894的java进程排在*(cpu占用142%),进程ID为574的java进程排在第二(cpu占用16%)。

超级干货:3个性能监控和优化命令详解

敲击键盘“x”(打开/关闭排序列的加亮效果),top的视图变化如下:

超级干货:3个性能监控和优化命令详解

可以看到,top默认的排序列是“%CPU”。

4.通过”shift + >”或”shift + <”可以向右或左改变排序列

下图是按一次”shift + >”的效果图,视图现在已经按照%MEM来排序。

 

2、free 命令

free命令可以显示Linux系统中空闲的、已用的物理内存及swap内存,及被内核使用的buffer。在Linux系统监控的工具中,free命令是*经常使用的命令之一。

1.命令格式:

free [参数]

2.命令功能:

free 命令显示系统使用和空闲的内存情况,包括物理内存、交互区内存(swap)和内核缓冲区内存。共享内存将被忽略

3.命令参数:

  • -b 以Byte为单位显示内存使用情况。
  • -k 以KB为单位显示内存使用情况。
  • -m 以MB为单位显示内存使用情况。
  • -g 以GB为单位显示内存使用情况。
  • -o 不显示缓冲区调节列。
  • -s <间隔秒数> 持续观察内存使用状况。
  • -t 显示内存总和列。
  • -V 显示版本信息。

4.使用实例:

实例1:显示内存使用情况

命令:


freefree -gfree -m

输出:


[root@SF1150 service]# free total used free shared buffers cachedMem: 32940112 30841684 2098428 0 4545340 11363424-/+ buffers/cache: 14932920 18007192Swap: 32764556 1944984 30819572[root@SF1150 service]# free -g total used free shared buffers cachedMem: 31 29 2 0 4 10-/+ buffers/cache: 14 17Swap: 31 1 29[root@SF1150 service]# free -m total used free shared buffers cachedMem: 32168 30119 2048 0 4438 11097-/+ buffers/cache: 14583 17584Swap: 31996 1899 30097

说明:

下面是对这些数值的解释:

  • total:总计物理内存的大小。
  • used:已使用多大。
  • free:可用有多少。
  • Shared:多个进程共享的内存总额。
  • Buffers/cached:磁盘缓存的大小。

第三行(-/+ buffers/cached):

  • used:已使用多大。
  • free:可用有多少。

第四行是交换分区SWAP的,也就是我们通常所说的虚拟内存。

区别:第二行(mem)的used/free与第三行(-/+ buffers/cache) used/free的区别。

这两个的区别在于使用的角度来看,*行是从OS的角度来看,因为对于OS,buffers/cached 都是属于被使用,所以他的可用内存是 2098428 KB,已用内存是30841684KB,其中包括,内核(OS)使用+Application(X, oracle,etc)使用的+buffers+cached。

第三行所指的是从应用程序角度来看,对于应用程序来说,buffers/cached 是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。

所以从应用程序的角度来说,可用内存=系统free memory+buffers+cached。

如本机情况的可用内存为:

18007156=2098428KB+4545340KB+11363424KB

接下来解释什么时候内存会被交换,以及按什么方交换。

当可用内存少于额定值的时候,就会开会进行交换.如何看额定值:

命令:


cat /proc/meminfo

输出:

[root@SF1150 service]# cat /proc/meminfoMemTotal: 32940112 kBMemFree: 2096700 kBBuffers: 4545340 kBCached: 11364056 kBSwapCached: 1896080 kBActive: 22739776 kBInactive: 7427836 kBHighTotal: 0 kBHighFree: 0 kBLowTotal: 32940112 kBLowFree: 2096700 kBSwapTotal: 32764556 kBSwapFree: 30819572 kBDirty: 164 kBWriteback: 0 kBAnonPages: 14153592 kBMapped: 20748 kBSlab: 590232 kBPageTables: 34200 kBNFS_Unstable: 0 kBBounce: 0 kBCommitLimit: 49234612 kBCommitted_AS: 23247544 kBVmallocTotal: 34359738367 kBVmallocUsed: 278840 kBVmallocChunk: 34359459371 kBHugePages_Total: 0HugePages_Free: 0HugePages_Rsvd: 0Hugepagesize: 2048 kB
交换将通过三个途径来减少系统中使用的物理页面的个数: 
  1. 减少缓冲与页面cache的大小,
  2. 将系统V类型的内存页面交换出去,
  3. 换出或者丢弃页面。(Application 占用的内存页,也就是物理内存不足)。

事实上,少量地使用swap是不是影响到系统性能的。

那 buffers 和 cached 都是缓存,两者有什么区别呢?

为了提高磁盘存取效率,Linux 做了一些精心的设计,除了对 dentry 进行缓存(用于VFS,加速文件路径名到 inode 的转换),还采取了两种主要 Cache 方式:Buffer Cache 和Page Cache。前者针对磁盘块的读写,后者针对文件 inode 的读写。这些 Cache 有效缩短了 I/O 系统调用(比如 read,write,getdents)的时间。

磁盘的操作有逻辑级(文件系统)和物理级(磁盘块),这两种Cache就是分别缓存逻辑和物理级数据的。

Page cache 实际上是针对文件系统的,是文件的缓存,在文件层面上的数据会缓存到page cache。文件的逻辑层需要映射到实际的物理磁盘,这种映射关系由文件系统来完成。当 page cache 的数据需要刷新时,page cache 中的数据交给 buffer cache,因为Buffer Cache 就是缓存磁盘块的。但是这种处理在 2.6 版本的内核之后就变的很简单了,没有真正意义上的 cache 操作。

Buffer cache 是针对磁盘块的缓存,也就是在没有文件系统的情况下,直接对磁盘进行操作的数据会缓存到buffer cache中,例如,文件系统的元数据都会缓存到buffer cache中。

简单说来,page cache 用来缓存文件数据,buffer cache 用来缓存磁盘数据。在有文件系统的情况下,对文件操作,那么数据会缓存到 page cache,如果直接采用dd等工具对磁盘进行读写,那么数据会缓存到 buffer cache。

所以我们看linux,只要不用swap的交换空间,就不用担心自己的内存太少.如果常常swap用很多,可能你就要考虑加物理内存了。这也是linux看内存是否够用的标准。

如果是应用服务器的话,一般只看第二行,+buffers/cache,即对应用程序来说free的内存太少了,也是该考虑优化程序或加内存了。

实例2:以总和的形式显示内存的使用信息

命令:


free -t

输出:

[root@SF1150 service]# free -t  total used free shared buffers cachedMem: 32940112 30845024 2095088 0 4545340 11364324-/+ buffers/cache: 14935360 18004752Swap: 32764556 1944984 30819572Total: 65704668 32790008 32914660[root@SF1150 service]#
说明:

实例3:周期性的查询内存使用信息

命令:


free -s 10

输出:


[root@SF1150 service]# free -s 10 total used free shared buffers cachedMem: 32940112 30844528 2095584 0 4545340 11364380-/+ buffers/cache: 14934808 18005304Swap: 32764556 1944984 30819572 total used free shared buffers cachedMem: 32940112 30843932 2096180 0 4545340 11364388-/+ buffers/cache: 14934204 18005908Swap: 32764556 1944984 30819572

 

3、vmstat

vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监控。他是对系统的整体情况进行统计,不足之处是无法对某个进程进行深入分析。vmstat 工具提供了一种低开销的系统性能观察方式。因为 vmstat 本身就是低开销工具,在非常高负荷的服务器上,你需要查看并监控系统的健康情况,在控制窗口还是能够使用vmstat 输出结果。在学习vmstat命令前,我们先了解一下Linux系统中关于物理内存和虚拟内存相关信息。

物理内存和虚拟内存区别:

我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概念。

物理内存就是系统硬件提供的内存大小,是真正的内存,相对于物理内存,在linux下还有一个虚拟内存的概念,虚拟内存就是为了满足物理内存的不足而提出的策略,它是利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(Swap Space)。

作为物理内存的扩展,linux会在物理内存不足时,使用交换分区的虚拟内存,更详细的说,就是内核会将暂时不用的内存块信息写到交换空间,这样以来,物理内存得到了释放,这块内存就可以用于其free命令可以显示Linux系统中空闲的、已用的物理内存及swap内存,及被内核使用的buffer。在Linux系统监控的工具中,free命令是*经常使用的命令之一。

1.命令格式:


free [参数]

2.命令功能:

free 命令显示系统使用和空闲的内存情况,包括物理内存、交互区内存(swap)和内核缓冲区内存。共享内存将被忽略

3.命令参数:

  • -b 以Byte为单位显示内存使用情况。
  • -k 以KB为单位显示内存使用情况。
  • -m 以MB为单位显示内存使用情况。
  • -g 以GB为单位显示内存使用情况。
  • -o 不显示缓冲区调节列。
  • -s<间隔秒数> 持续观察内存使用状况。
  • -t 显示内存总和列。
  • -V 显示版本信息。

4.使用实例:

实例1:显示内存使用情况

命令:


freefree -gfree -m

输出:


[root@SF1150 service]# free total used free shared buffers cachedMem: 32940112 30841684 2098428 0 4545340 11363424-/+ buffers/cache: 14932920 18007192Swap: 32764556 1944984 30819572[root@SF1150 service]# free -g total used free shared buffers cachedMem: 31 29 2 0 4 10-/+ buffers/cache: 14 17Swap: 31 1 29[root@SF1150 service]# free -m total used free shared buffers cachedMem: 32168 30119 2048 0 4438 11097-/+ buffers/cache: 14583 17584Swap: 31996 1899 30097

它目的,当需要用到原始的内容时,这些信息会被重新从交换空间读入物理内存。

linux的内存管理采取的是分页存取机制,为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中,而将经常使用的信息保留到物理内存。

要深入了解linux内存运行机制,需要知道下面提到的几个方面:

首先,Linux系统会不时的进行页面交换操作,以保持尽可能多的空闲物理内存,即使并没有什么事情需要内存,Linux也会交换出暂时不用的内存页面。这可以避免等待交换所需的时间。

其次,linux进行页面交换是有条件的,不是所有页面在不用时都交换到虚拟内存,linux内核根据”*近*经常使用“算法,仅仅将一些不经常使用的页面文件交换到虚拟内存,有时我们会看到这么一个现象:linux物理内存还有很多,但是交换空间也使用了很多。其实,这并不奇怪,例如,一个占用很大内存的进程运行时,需要耗费很多内存资源,此时就会有一些不常用页面文件被交换到虚拟内存中,但后来这个占用很多内存资源的进程结束并释放了很多内存时,刚才被交换出去的页面文件并不会自动的交换进物理内存,除非有这个必要,那么此刻系统物理内存就会空闲很多,同时交换空间也在被使用,就出现了刚才所说的现象了。关于这点,不用担心什么,只要知道是怎么一回事就可以了。

*后,交换空间的页面在使用时会首先被交换到物理内存,如果此时没有足够的物理内存来容纳这些页面,它们又会被马上交换出去,如此以来,虚拟内存中可能没有足够空间来存储这些交换页面,*终会导致linux出现假死机、服务异常等问题,linux虽然可以在一段时间内自行恢复,但是恢复后的系统已经基本不可用了。

因此,合理规划和设计linux内存的使用,是非常重要的。

虚拟内存原理:

在系统中运行的每个进程都需要使用到内存,但不是每个进程都需要每时每刻使用系统分配的内存空间。当系统运行所需内存超过实际的物理内存,内核会释放某些进程所占用但未使用的部分或所有物理内存,将这部分资料存储在磁盘上直到进程下一次调用,并将释放出的内存提供给有需要的进程使用。

在Linux内存管理中,主要是通过“调页Paging”和“交换Swapping”来完成上述的内存调度。调页算法是将内存中*近不常使用的页面换到磁盘上,把活动页面保留在内存中供进程使用。交换技术是将整个进程,而不是部分页面,全部交换到磁盘上。

分页(Page)写入磁盘的过程被称作Page-Out,分页(Page)从磁盘重新回到内存的过程被称作Page-In。当内核需要一个分页时,但发现此分页不在物理内存中(因为已经被Page-Out了),此时就发生了分页错误(Page Fault)。

当系统内核发现可运行内存变少时,就会通过Page-Out来释放一部分物理内存。经管Page-Out不是经常发生,但是如果Page-out频繁不断的发生,直到当内核管理分页的时间超过运行程式的时间时,系统效能会急剧下降。这时的系统已经运行非常慢或进入暂停状态,这种状态亦被称作thrashing(颠簸)。

1.命令格式:


vmstat [-a] [-n] [-S unit] [delay [ count]]vmstat [-s] [-n] [-S unit]vmstat [-m] [-n] [delay [ count]]vmstat [-d] [-n] [delay [ count]]vmstat [-p disk partition] [-n] [delay [ count]]vmstat [-f]vmstat [-V]

2.命令功能:

用来显示虚拟内存的信息

3.命令参数:

  • -a:显示活跃和非活跃内存
  • -f:显示从系统启动至今的fork数量 。
  • -m:显示slabinfo
  • -n:只在开始时显示一次各字段名称。
  • -s:显示内存相关统计信息及多种系统活动数量。
  • delay:刷新时间间隔。如果不指定,只显示一条结果。
  • count:刷新次数。如果不指定刷新次数,但指定了刷新时间间隔,这时刷新次数为无穷。
  • -d:显示磁盘相关统计信息。
  • -p:显示指定磁盘分区统计信息
  • -S:使用指定单位显示。参数有 k 、K 、m 、M ,分别代表1000、1024、1000000、1048576字节(byte)。默认单位为K(1024 bytes)
  • -V:显示vmstat版本信息。

4.使用实例:

实例1:显示虚拟内存使用情况命令:


vmstat

输出:

说明:字段说明:

  • Procs(进程):
  • r: 运行队列中进程数量
  • b: 等待IO的进程数量
  • Memory(内存):
  • swpd: 使用虚拟内存大小
  • free: 可用内存大小
  • buff: 用作缓冲的内存大小
  • cache: 用作缓存的内存大小

Swap:

  • si: 每秒从交换区写到内存的大小
  • so: 每秒写入交换区的内存大小
  • IO:(现在的Linux版本块的大小为1024bytes)
  • bi: 每秒读取的块数
  • bo: 每秒写入的块数

系统:

  • in: 每秒中断数,包括时钟中断。
  • cs: 每秒上下文切换数。
  • CPU(以百分比表示):
  • us: 用户进程执行时间(user time)
  • sy: 系统进程执行时间(system time)
  • id: 空闲时间(包括IO等待时间),中央处理器的空闲时间 。以百分比表示。
  • wa: 等待IO时间

备注:如果 r经常大于 4 ,且id经常少于40,表示cpu的负荷很重。如果pi,po 长期不等于0,表示内存不足。如果disk 经常不等于0, 且在 b中的队列 大于3, 表示 io性能不好。Linux在具有高稳定性、可靠性的同时,具有很好的可伸缩性和扩展性,能够针对不同的应用和硬件环境调整,优化出满足当前应用需要的*佳性能。因此企业在维护Linux系统、进行系统调优时,了解系统性能分析工具是至关重要的。

命令:

vmstat 5 5

表示在5秒时间内进行5次采样。将得到一个数据汇总他能够反映真正的系统情况。

实例2:显示活跃和非活跃内存

命令:


vmstat -a 2 5

输出:


[root@localhost ~]# vmstat -a 2 5procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ r b swpd free inact active si so bi bo in cs us sy id wa st 0 0 0 3029752 387728 513008 0 0 0 2 3 2 0 0 100 0 0 0 0 0 3029752 387728 513076 0 0 0 0 1005 34 0 0 100 0 0 0 0 0 3029752 387728 513076 0 0 0 22 1004 36 0 0 100 0 0 0 0 0 3029752 387728 513076 0 0 0 0 1004 33 0 0 100 0 0 0 0 0 3029752 387728 513076 0 0 0 0 1003 32 0 0 100 0 0

说明:

使用-a选项显示活跃和非活跃内存时,所显示的内容除增加inact和active外,其他显示内容与例子1相同。字段说明:

  • Memory(内存):
  • inact: 非活跃内存大小(当使用-a选项时显示)
  • active: 活跃的内存大小(当使用-a选项时显示)

实例3:查看系统已经fork了多少次

命令:


vmstat -f

输出:


[root@SCF1129 ~]# vmstat -f 12744849 forks[root@SCF1129 ~]#

说明:这个数据是从/proc/stat中的processes字段里取得的

实例4:查看内存使用的详细信息

命令:


vmstat -s

输出:


[root@localhost ~]# vmstat -s 4043760 total memory 1013884 used memory 513012 active memory 387728 inactive memory 3029876 free memory 199616 buffer memory 690980 swap cache 6096656 total swap 0 used swap 6096656 free swap 83587 non-nice user cpu ticks 132 nice user cpu ticks 278599 system cpu ticks 913344692 idle cpu ticks 814550 IO-wait cpu ticks 10547 IRQ cpu ticks 21261 softirq cpu ticks 0 stolen cpu ticks 310215 pages paged in 14254652 pages paged out 0 pages swapped in 0 pages swapped out 288374745 interrupts 146680577 CPU context switches 1351868832 boot time 367291 forks

说明:这些信息的分别来自于/proc/meminfo,/proc/stat和/proc/vmstat。

实例5:查看磁盘的读/写

命令:


vmstat -d

输出:


[root@localhost ~]# vmstat -ddisk- ------------reads------------ ------------writes----------- -----IO------ total merged sectors ms total merged sectors ms cur secram0 0 0 0 0 0 0 0 0 0 0ram1 0 0 0 0 0 0 0 0 0 0ram2 0 0 0 0 0 0 0 0 0 0ram3 0 0 0 0 0 0 0 0 0 0ram4 0 0 0 0 0 0 0 0 0 0ram5 0 0 0 0 0 0 0 0 0 0ram6 0 0 0 0 0 0 0 0 0 0ram7 0 0 0 0 0 0 0 0 0 0ram8 0 0 0 0 0 0 0 0 0 0ram9 0 0 0 0 0 0 0 0 0 0ram10 0 0 0 0 0 0 0 0 0 0ram11 0 0 0 0 0 0 0 0 0 0ram12 0 0 0 0 0 0 0 0 0 0ram13 0 0 0 0 0 0 0 0 0 0ram14 0 0 0 0 0 0 0 0 0 0ram15 0 0 0 0 0 0 0 0 0 0sda 33381 6455 615407 63224 2068111 1495416 28508288 15990289 0 10491hdc 0 0 0 0 0 0 0 0 0 0fd0 0 0 0 0 0 0 0 0 0 0md0 0 0 0 0 0 0 0 0 0 0[root@localhost ~]#

说明:

这些信息主要来自于/proc/diskstats.

merged:表示一次来自于合并的写/读请求,一般系统会把多个连接/邻近的读/写请求合并到一起来操作.

实例6:查看/dev/sda1磁盘的读/写

命令:输出:

[root@SCF1129 ~]# df文件系统 1K-块 已用 可用 已用% 挂载点/dev/sda3 1119336548 27642068 1034835500 3% /tmpfs 32978376 0 32978376 0% /dev/shm/dev/sda1 1032088 59604 920056 7% /boot[root@SCF1129 ~]# vmstat -p /dev/sda1sda1 reads read sectors writes requested writes 18607 4249978 6 48[root@SCF1129 ~]# vmstat -p /dev/sda3sda3 reads read sectors writes requested writes 429350 35176268 28998789 980301488[root@SCF1129 ~]#

说明:

这些信息主要来自于/proc/diskstats。

reads:来自于这个分区的读的次数。

read sectors:来自于这个分区的读扇区的次数。

writes:来自于这个分区的写的次数。

requested writes:来自于这个分区的写请求次数。

实例7:查看系统的 slab 信息

命令:

vmstat -m

输出:

[root@localhost ~]# vmstat -mCache Num Total Size Pagesip_conntrack_expect 0 0 136 28ip_conntrack 3 13 304 13ip_fib_alias 11 59 64 59ip_fib_hash 11 59 64 59AF_VMCI 0 0 960 4bio_map_info 100 105 1064 7dm_mpath 0 0 1064 7jbd_4k 0 0 4096 1dm_uevent 0 0 2608 3dm_tio 0 0 24 144dm_io 0 0 48 77scsi_cmd_cache 10 10 384 10sgpool-128 32 32 4096 1sgpool-64 32 32 2048 2sgpool-32 32 32 1024 4sgpool-16 32 32 512 8sgpool-8 45 45 256 15scsi_io_context 0 0 112 34ext3_inode_cache 51080 51105 760 5ext3_xattr 36 88 88 44journal_handle 18 144 24 144journal_head 56 80 96 40revoke_table 4 202 16 202revoke_record 0 0 32 112uhci_urb_priv 0 0 56 67UNIX 13 33 704 11flow_cache 0 0 128 30msi_cache 33 59 64 59cfq_ioc_pool 14 90 128 30cfq_pool 12 90 216 18crq_pool 16 96 80 48deadline_drq 0 0 80 48as_arq 0 0 96 40mqueue_inode_cache 1 4 896 4isofs_inode_cache 0 0 608 6hugetlbfs_inode_cache 1 7 576 7Cache Num Total Size Pagesext2_inode_cache 0 0 720 5ext2_xattr 0 0 88 44dnotify_cache 0 0 40 92dquot 0 0 256 15eventpoll_pwq 3 53 72 53eventpoll_epi 3 20 192 20inotify_event_cache 0 0 40 92inotify_watch_cache 1 53 72 53kioctx 0 0 320 12kiocb 0 0 256 15fasync_cache 0 0 24 144shmem_inode_cache 254 290 768 5posix_timers_cache 0 0 128 30uid_cache 0 0 128 30ip_mrt_cache 0 0 128 30tcp_bind_bucket 3 112 32 112inet_peer_cache 0 0 128 30secpath_cache 0 0 64 59xfrm_dst_cache 0 0 384 10ip_dst_cache 5 10 384 10arp_cache 1 15 256 15RAW 3 5 768 5UDP 5 10 768 5tw_sock_TCP 0 0 192 20request_sock_TCP 0 0 128 30TCP 4 5 1600 5blkdev_ioc 14 118 64 59blkdev_queue 20 30 1576 5blkdev_requests 13 42 272 14biovec-256 7 7 4096 1biovec-128 7 8 2048 2biovec-64 7 8 1024 4biovec-16 7 15 256 15biovec-4 7 59 64 59biovec-1 23 202 16 202bio 270 270 128 30utrace_engine_cache 0 0 64 59Cache Num Total Size Pagesutrace_cache 0 0 64 59sock_inode_cache 33 48 640 6skbuff_fclone_cache 7 7 512 7skbuff_head_cache 319 390 256 15file_lock_cache 1 22 176 22Acpi-Operand 4136 4248 64 59Acpi-ParseExt 0 0 64 59Acpi-Parse 0 0 40 92Acpi-State 0 0 80 48Acpi-Namespace 2871 2912 32 112delayacct_cache 81 295 64 59taskstats_cache 4 53 72 53proc_inode_cache 1427 1440 592 6sigqueue 0 0 160 24radix_tree_node 13166 13188 536 7bdev_cache 23 24 832 4sysfs_dir_cache 5370 5412 88 44mnt_cache 26 30 256 15inode_cache 2009 2009 560 7dentry_cache 60952 61020 216 18filp 479 1305 256 15names_cache 3 3 4096 1avc_node 14 53 72 53selinux_inode_security 994 1200 80 48key_jar 2 20 192 20idr_layer_cache 74 77 528 7buffer_head 164045 164800 96 40mm_struct 51 56 896 4vm_area_struct 1142 1958 176 22fs_cache 35 177 64 59files_cache 36 55 768 5signal_cache 72 162 832 9sighand_cache 68 84 2112 3task_struct 76 80 1888 2anon_vma 458 864 24 144pid 83 295 64 59shared_policy_node 0 0 48 77Cache Num Total Size Pagesnuma_policy 37 144 24 144size-131072(DMA) 0 0 131072 1size-131072 0 0 131072 1size-65536(DMA) 0 0 65536 1size-65536 1 1 65536 1size-32768(DMA) 0 0 32768 1size-32768 2 2 32768 1size-16384(DMA) 0 0 16384 1size-16384 5 5 16384 1size-8192(DMA) 0 0 8192 1size-8192 7 7 8192 1size-4096(DMA) 0 0 4096 1size-4096 110 111 4096 1size-2048(DMA) 0 0 2048 2size-2048 602 602 2048 2size-1024(DMA) 0 0 1024 4size-1024 344 352 1024 4size-512(DMA) 0 0 512 8size-512 433 480 512 8size-256(DMA) 0 0 256 15size-256 1139 1155 256 15size-128(DMA) 0 0 128 30size-64(DMA) 0 0 64 59size-64 5639 5782 64 59size-32(DMA) 0 0 32 112size-128 801 930 128 30size-32 3005 3024 32 112kmem_cache 137 137 2688 1

这组信息来自于/proc/slabinfo。

slab:由于内核会有许多小对象,这些对象构造销毁十分频繁,比如i-node,dentry,这些对象如果每次构建的时候就向内存要一个页(4kb),而其实只有几个字节,这样就会非常浪费,为了解决这个问题,就引入了一种新的机制来处理在同一个页框中如何分配小存储区,而slab可以对小对象进行分配,这样就不用为每一个对象分配页框,从而节省了空间,内核对一些小对象创建析构很频繁,slab对这些小对象进行缓冲,可以重复利用,减少内存分配次数。

iOS Mac系统下Ruby环境安装与CocoaPods使用

1,如何在Mac OS X上安装 Ruby运行环境
2,安装CocoaPots的顺序:Xcode->homebrew->RVM->Ruby->CocoaPats;
3,CocoaPods是什么?
4,如何下载和安装CocoaPods?
5,如何使用CocoaPods?

一:在安装CocoaPods之前要先配置好RUBY环境,本文就怎么安装RUBY的环境进行一总结。安装Ruby环境首先需要安装Xcode然后需要安装Homebrew,接下来需要安装RVM*后安装Ruby环境。安装XCode就不用说了
二:Homebrew是一个包管理器;

1,中文地址:http://brew.sh/index_zh-cn.html

打开终端(Terminal)把以下粘贴到终端内:

ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”

2,安装设置RVM

命令:curl -L https://get.rvm.io | bash -s stable

3, 设置RVM,通过以下命令启用RVM

source ~/.rvm/scripts/rvm

检查一下是否安装正确命令

rvm -v

正确的话会出现类似下面的文字

rvm 1.26.11 (master) by Wayne E. Seguin <yuanwangyund@gmail.com>, Michal Papis <mpapis@gmail.com> [https://rvm.io/]

4.安装RUBY

rvm install 2.0.0

漫长的等待下载过程,安装完成后需要执行下面的命令指定哪个RUBY为系统默认的

rvm 2.0.0 –default

接下来就重点阐述CocoaPods的详细思路讲解,CocoaPods是什么,CocoaPods怎么使用安装;

CocoaPods是OSX和iOS下的一个第三类库管理工具,通过CocoaPods工具我们可以为项目添加被称为“Pods”的依赖库(这些类库必须是CocoaPods本身所支持的),并且可以轻松管理其版本。
在安装CocoaPods之前,首先要在本地安装好Ruby环境。至于如何在Mac中安装好Ruby环境,
Cocoapods安装步骤
1,假如你在本地已经安装好Ruby环境,那么下载和安装CocoaPods将十分简单,只需要一行命令

sudo gem install cocoapods

2,我们可以用淘宝的Ruby镜像来访问cocoapods。按照下面的顺序在终端中敲入依次敲入命令:

gem sources –remove https://rubygems.org/
出现提示之后再执行:
gem sources -a http://ruby.taobao.org/

3,验证你的Ruby镜像是不是taobao,可以用以下命令查看:

gem sources -l

4,*后,在终端中出现下面文字才表明你上面的命令是成功的:

*** CURRENT SOURCES ***

http://ruby.taobao.org/

5,这时候,你再次在终端中运行:

sudo gem install cocoapods

二:CocoaPods的使用
1、首先我们来搜索一下三方库

终端输入:$ pod search AFNetworking

这样依次执行就完成了。
2,此时,就是建立Podfile(配置文件),这些如果需要的,可以看博主下一次更新;
3,此篇文章先阐述到此为止,若有疑问可以私信博主,希望对大家有所帮助,谢谢你的阅读,nice!

三:导入pods项目文件以及开源库
1,输入cd 导入工程项目文件

2,pod init ,此时文件夹会多一个podflle文件

%title插图%num

3,右击用编译器打开,在end上添加所需要用到的开源库,如:pod ‘AFNetworking’, ‘~> 3.0’

%title插图%num

4,进入终端,输入pod install,会自动生成开源库到项目文件里;

%title插图%num
5,Pods文件的导入都搞好了,以后进入项目就可以直接点击这个进入了,所有的开源库都在pods文件夹里。

%title插图%num

linux htop命令详解

在 Linux 系统中,top 命令用来显示系统中正在运行的进程的实时状态,它显示了一些非常有用的信息,比如 CPU 利用情况、内存消耗情况,以及每个进程情况等。但是,你知道吗?还有另外一个命令行工具 ‘htop’,它与传统的 top 命令功能一样,但它有更加强大的功能及能显示更多的信息。这篇文章,我们会用实例来讨论这个 ‘htop’ 命令。

Linux 中的 htop 命令

下面是从 htop 的手册页摘抄下来的相关描述:

它类似于 top 命令,但可以让你在垂直和水平方向上滚动,所以你可以看到系统上运行的所有进程,以及他们完整的命令行。

可以不用输入进程的 PID 就可以对此进程进行相关的操作 (killing, renicing)。

首先明白它的输出

htop 命令以直观的格式来显示信息。下面是 HTOP 的输出快照:

htop

htop

如果你观察窗口的左上角部分,你会看到显示的是 CPU 负载、内存消耗及交换空间的实时信息,右上角包含的是任务、线程、平均负载及系统运行时间的信息。

平均负载部分提供了三个数字,这仅仅表示的是过去的5分钟、10分钟和15分钟系统的平均负载而已,在单核的系统中,平均负载为1表示的是百分之百的 CPU 利用率。*后,运行时间 (uptime)标示的数字是从系统启动起到当前的运行总时间。

下面,我们将用例子来进一步讨论这个命令。

1. 用 F2 键编辑配置

htop 命令提供了许多自定义选项,你所要做的就是从主窗口中按下 F2 键。

下面所示的是可用的自定义选项:

htop-settings

htop-settings

只需使用箭头键选择和更改特定的设置。

2. 通过 F9 键发送信号

htop 命令可以让你很容易地在 htop 窗口内给一个进程发送任意的信号。按下 F9 键即可。

signals

signals

如你所见,窗口的左边部分列出的是所有可用的信号,右边部分列出的是进程。只要选中信号,并选择一个进程,然后按下 enter 键,选中的信号就会发送到此进程。

3. 显示进程的树状视图

htop 命令也提供了进程的树状视图查看功能。按下 F5 键切换。

下面是 htop 显示树形视图信息的例子:

treeView

treeView

要退出树状视图模式,请再一次按下 F5 键。

4. 通过 F3 键搜索进程

htop 命令提供了易用的方式来搜索进程。按下 F3 键,一个文本框就会出现在窗口底部。

下面是例子:

search

search

如您所见,一条名为‘搜索’的文本提示框出现在窗口底部,您可以在这儿输入进程的名字然后回车搜索。如果找到,它会在列出的进程列表里高亮选中此进程。

5. 通过空格键来设置颜色标注进程条目

在系统中运行着的实时进程视图中,要追踪某个进程是个大问题。因为整个列表在不停的刷新着,进程的排列顺序也在变动着。为了这个问题, htop 提供了一个很简单的解决方案:颜色标注。是的,你可以标注一个进程条目,它会以不同的颜色显示,因此要追踪它就变得容易了。

要标注某个进程条目,需要做的就是选中此条目,然后按下‘空格’键。例如,在下面的截图示例中,我已经颜色标注了三个进程条目:

color-tag

color-tag

所以通过此方法,你就能很轻松地追踪想查看的进程。

6. 命令行选项

除了上面介绍的一些热键,htop 还提供了很有用的命令行选项。下面是其中一部分:

  • -s 选项 : 按指定的列排序。例如,htop -s PID 命令会按 PID 列的大小排序来显示。
  • -u 选项 : 显示指定的用户的进程信息列表。例如,htop -u himanshu 命令会只显示出用户名为 himanshu 的相关进程。
  • -d 选项 : 设置刷新的延迟时间。例如,htop -d 100 命令会使输出在1秒后才会刷新(参数 -d 的单位是10微秒)。
友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速