首页 文章 精选 留言 我的

精选列表

搜索[编译原理],共10000篇文章
优秀的个人博客,低调大师

性能测试分析与调优原理

最近一直纠结性能分析与调优如何下手,先从硬件开始,还是先从代码或数据库。从操作系统(CPU调度,内存管理,进程调度,磁盘I/O)、网络、协议(HTTP,TCP/IP),还是从应用程序代码,数据库调优,中间件配置等方面入手。 单一个中间件又分web中间件(apache、IIS),应用中间件(tomcat、weblogic、webSphere)等,虽然都是中间件,每一样拎出来往深了学都不是一朝一夕之功。但调优对于每一项的要求又不仅仅是“知道”或“会使用”这么简单。起码要达到“如何更好的使用”。 常看到性能测试书中说,性能测试不单单是性能测试工程师一个人的事儿。需要DBA、开发人员、运维人员的配合完成。但是在不少情况下性能测试是由性能测试人员独立完成的,退一步就算由其它人员的协助,了解系统架构的的各个模块对于自身的提高也有很大帮助,同进也更能得到别人的尊重。 再说性能调优之前,我们有必要再提一下进行测试的目的,或者我们进行性能测试的初衷是什么? 能力验证:验证某系统在一定条件具有什么样的能力。 能力规划:如何使系统达到我们要求的性能能力。 应用程序诊断:比如内存泄漏,通过功能测试很难发现,但通过性能测试却很容易发现。 性能调优:满足用户需求,进一步进行系统分析找出瓶颈,优化瓶颈,提高系统整体性能。 一般系统的瓶颈 性能测试调优需要先发现瓶颈,那么系统一般会存在哪些瓶颈: 硬件上的性能瓶颈: 一般指的是CPU、内存、磁盘I/O方面的问题,分为服务器硬件瓶颈、网络瓶颈(对局域网可以不考虑)、服务器操作系统瓶颈(参数配置)、中间件瓶颈(参数配置、数据库、web服务器等)、应用瓶颈(SQL语句、数据库设计、业务逻辑、算法等)。 应用软件上的性能瓶颈: 一般指的是应用服务器、web服务器等应用软件,还包括数据库系统。 例如:中间件weblogic平台上配置的JDBC连接池的参数设置不合理,造成的瓶颈。 应用程序上的性能瓶颈: 一般指的是开发人员新开发出来的应用程序。 例如,程序架构规划不合理,程序本身设计有问题(串行处理、请求的处理线程不够),造成系统在大量用户方位时性能低下而造成的瓶颈。 操作系统上的性能瓶颈: 一般指的是windows、UNIX、Linux等操作系统。 例如,在进行性能测试,出现物理内存不足时,虚拟内存设置也不合理,虚拟内存的交换效率就会大大降低,从而导致行为的响应时间大大增加,这时认为操作系统上出现性能瓶颈。 网络设备上的性能瓶颈: 一般指的是防火墙、动态负载均衡器、交换机等设备。 例如,在动态负载均衡器上设置了动态分发负载的机制,当发现某个应用服务器上的硬件资源已经到达极限时,动态负载均衡器将后续的交易请求发送到其他负载较轻的应用服务器上。在测试时发现,动态负载均衡器没有起到相应的作用,这时可以认为网络瓶颈。 性能测试出现的原因及其定位十分复杂,这里只是简单介绍常见的几种瓶颈类型和特征,而性能测试所需要做的就是根据各种情况因素综合考虑,然后协助开发人员\DBA\运维人员一起定位性能瓶颈。 一般性能调优步骤 一般性能问题调优的步骤: 步骤一:确定问题 应用程序代码:在通常情况下,很多程序的性能问题都是写出来的,因此对于发现瓶颈的模块,应该首先检查一下代码。 数据库配置:经常引起整个系统运行缓慢,一些诸如oracle的大型数据库都是需要DBA进行正确的参数调整才能投产的。 操作系统配置:不合理就可能引起系统瓶颈。 硬件设置:硬盘速度、内存大小等都是容易引起瓶颈的原因,因此这些都是分析的重点。 网络:网络负载过重导致网络冲突和网络延迟。 步骤二:分析问题 当确定了问题之后,我们要明确这个问题影响的是响应时间吞吐量,还是其他问题?是多数用户还是少数用户遇到了问题?如果是少数用户,这几个用户与其它用户的操作有什么不同?系统资源监控的结果是否正常?CPU的使用是否到达极限?I/O情况如何?问题是否集中在某一类模块中?是客户端还是服务器出现问题?系统硬件配置是否够用?实际负载是否超过了系统的负载能力?是否未对系统进行优化? 通过这些分析一些与系统相关的问题,可以对系统瓶颈有更深入的了解,进而分析出真正的原因。 步骤三:确定调整目标和解决方案 提高系统吞吐量,缩短响应时间,更好地支持并发。 步骤四:测试解决方案 对通过解决方案调优后的系统进行基准测试。(基准测试是指通过设计科学的测试方法、测试工具和测试系统,实现对一类测试对象的某项性能指标进行定量的和可对比的测试) 步骤五:分析调优结果 系统调优是否达到或者超出了预定目标?系统是整体性能得到了改善,还是以系统某部分性能来解决其他问题?调优是否可以结束了? 最后,如果达到了预期目标,调优工作就基本可以结束了。 下面算是一个技巧,如面试官问到一个性能问题假设,我不知道性能问题出在哪儿时,可以按照这个思路回答: 查找瓶颈时按以下顺序,由易到难。 服务器硬件瓶颈---〉网络瓶颈(对局域网,可以不考虑)---〉服务器操作系统瓶颈(参数配置)---〉中间件瓶颈(参数配置,数据库,web服务器等)---〉应用瓶颈(SQL语句、数据库设计、业务逻辑、算法等) 注:以上过程并不是每个分析中都需要的,要根据测试目的和要求来确定分析的深度。对一些要求低的,我们分析到应用系统在将来大的负载压力(并发用户数、数据量)下,系统的硬件瓶颈在哪儿就够了。 分段排除法 (很有效) 性能测试调优应该注意的要点: 要点1:在应用系统的设计开发过程中,应始终把性能放在考虑的范围内。 要点2: 确定清晰明确的性能目标是关键。 要点3:必须保证调优后的程序运行正确。 要点4:系统的性能更大程度上取决于良好的设计,调优技巧只是一个辅助手段。 要点5:调优过程是迭代渐进的过程,每一次调优的结果都要反馈到后续的代码开发中去。 要点6:性能调优不能以牺牲代码的可读性和可维护性为代码。 本文转自 昊洋教育 51CTO博客,原文链接:http://blog.51cto.com/zdytesting/1857798,如需转载请自行联系原作者

优秀的个人博客,低调大师

MySQL Replication(复制)基本原理

1、复制进程 Mysql的复制(replication)是一个异步的复制,从一个Mysql instace(称之为Master)复制到另一个Mysql instance(称之Slave)。实现整个复制操作主要由三个进程完成的,其中两个进程在Slave(Sql进程和IO进程),另外一个进程在 Master(IO进程)上。 要实施复制,首先必须打开Master端的binary log(bin-log)功能,否则无法实现。因为整个复制过程实际上就是Slave从Master端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。 复制的基本过程如下: 1)、Slave上面的IO进程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容; 2)、Master接收到来自Slave的IO进程的请求后,通过负责复制的IO进程根据请求信息读取制定日志指定位置之后的日志信息,返回给Slave 的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置; 3)、Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的 bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清楚的高速Master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”; 4)、Slave的Sql进程检测到relay-log中新增加了内容后,会马上解析relay-log的内容成为在Master端真实执行时候的那些可执行的内容,并在自身执行。 实际上在老版本的Mysql的复制实现在Slave端并不是两个进程完成的,而是由一个进程完成。但是后来发现这样做存在较大的风险和性能问题,主要如下: 首先,一个进程就使复制bin-log日志和解析日志并在自身执行的过程成为一个串行的过程,性能受到了一定的限制,异步复制的延迟也会比较长。 另外,Slave端从Master端获取bin-log过来之后,需要接着解析日志内容,然后在自身执行。在这个过程中,Master端可能又产生了大量变化并声称了大量的日志。如果在这个阶段Master端的存储出现了无法修复的错误,那么在这个阶段所产生的所有变更都将永远无法找回。如果在Slave 端的压力比较大的时候,这个过程的时间可能会比较长。 所以,后面版本的Mysql为了解决这个风险并提高复制的性能,将Slave端的复制改为两个进程来完成。提出这个改进方案的人是Yahoo!的一位工程师“Jeremy Zawodny”。这样既解决了性能问题,又缩短了异步的延时时间,同时也减少了可能存在的数据丢失量。当然,即使是换成了现在这样两个线程处理以后,同样也还是存在slave数据延时以及数据丢失的可能性的,毕竟这个复制是异步的。只要数据的更改不是在一个事物中,这些问题都是会存在的。如果要完全避免这些问题,就只能用mysql的cluster来解决了。不过mysql的cluster是内存数据库的解决方案,需要将所有数据都load到内存中,这样就对内存的要求就非常大了,对于一般的应用来说可实施性不是太大。 2、复制实现级别 Mysql的复制可以是基于一条语句(Statement level),也可以是基于一条记录(Row level),可以在Mysql的配置参数中设定这个复制级别,不同复制级别的设置会影响到Master端的bin-log记录成不同的形式。 Row Level:日志中会记录成每一行数据被修改的形式,然后在slave端再对相同的数据进行修改。 优点:在row level模式下,bin-log中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条记录被修改了,修改成什么样了。所以row level的日志内容会非常清楚的记录下每一行数据修改的细节,非常容易理解。而且不会出现某些特定情况下的存储过程,或function,以及 trigger的调用和触发无法被正确复制的问题。 缺点:row level下,所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容,比如有这样一条update语句:update product set owner_member_id = ‘b’ where owner_member_id = ‘a’,执行之后,日志中记录的不是这条update语句所对应额事件(mysql以事件的形式来记录bin-log日志),而是这条语句所更新的每一条记录的变化情况,这样就记录成很多条记录被更新的很多个事件。自然,bin-log日志的量就会很大。尤其是当执行alter table之类的语句的时候,产生的日志量是惊人的。因为Mysql对于alter table之类的表结构变更语句的处理方式是整个表的每一条记录都需要变动,实际上就是重建了整个表。那么该表的每一条记录都会被记录到日志中。 Statement Level:每一条会修改数据的sql都会记录到 master的bin-log中。slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql来再次执行。 优点:statement level下的优点首先就是解决了row level下的缺点,不需要记录每一行数据的变化,减少bin-log日志量,节约IO,提高性能。因为他只需要记录在Master上所执行的语句的细节,以及执行语句时候的上下文的信息。 缺点:由于他是记录的执行语句,所以,为了让这些语句在slave端也能正确执行,那么他还必须记录每条语句在执行的时候的一些相关信息,也就是上下文信息,以保证所有语句在slave端杯执行的时候能够得到和在master端执行时候相同的结果。另外就是,由于Mysql现在发展比较快,很多的新功能不断的加入,使mysql得复制遇到了不小的挑战,自然复制的时候涉及到越复杂的内容,bug也就越容易出现。在statement level下,目前已经发现的就有不少情况会造成mysql的复制出现问题,主要是修改数据的时候使用了某些特定的函数或者功能的时候会出现,比如:sleep()函数在有些版本中就不能真确复制,在存储过程中使用了last_insert_id()函数,可能会使slave和master上得到不一致的id等等。由于row level是基于每一行来记录的变化,所以不会出现类似的问题。 从官方文档中看到,之前的Mysql一直都只有基于statement的复制模式,直到5.1.5版本的Mysql才开始支持row level的复制。从5.0开始,Mysql的复制已经解决了大量老版本中出现的无法正确复制的问题。但是由于存储过程的出现,给Mysql的复制又带来了更大的新挑战。另外,看到官方文档说,从5.1.8版本开始,Mysql提供了除Statement Level和Row Level之外的第三种复制模式:Mixed,实际上就是前两种模式的结合。在Mixed模式下,Mysql会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。新版本中的Statment level还是和以前一样,仅仅记录执行的语句。而新版本的Mysql中队row level模式也被做了优化,并不是所有的修改都会以row level来记录,像遇到表结构变更的时候就会以statement模式来记录,如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。 3、复制常用架构 Mysql复制环境90%以上都是一个Master带一个或者多个Slave的架构模式,主要用于读压力比较大的应用的数据库端廉价扩展解决方案。因为只要master和slave的压力不是太大(尤其是slave端压力)的话,异步复制的延时一般都很少很少。尤其是自slave端的复制方式改成两个进程处理之后,更是减小了slave端的延时。而带来的效益是,对于数据实时性要求不是特别的敏感度的应用,只需要通过廉价的pc server来扩展slave的数量,将读压力分散到多台slave的机器上面,即可解决数据库端的读压力瓶颈。这在很大程度上解决了目前很多中小型网站的数据库压力瓶颈问题,甚至有些大型网站也在使用类似方案解决数据库瓶颈。 一个Master带多个slave的架构实施非常简单,多个slave和单个slave的实施并没有太大区别。在Master端并不care有多少个 slave连上了master端,只要有slave进程通过了连接认证,向他请求binlog信息,他就会按照连接上来的io进程的要求,读取自己的 binlog信息,返回给slave的IO进程。对于slave的配置细节,在Mysql的官方文档上面已经说的很清楚了,甚至介绍了多种实现slave 的配置方法。 Mysql不支持一个Slave instance从属于多个Master的架构。就是说,一个slave instance只能接受一个master的同步源,听说有patch可以改进这样的功能,但没有实践过。Mysql AB之所以不实现这样的功能,主要是考虑到冲突解决的问题。 Mysql也可以搭建成dual master模式,也就是说两个Mysql instance互为对方的Master,也同时为对方的Slave。不过一般这种架构也是只有一端提供服务,避免冲突问题。因为即使在两边执行的修改有先后顺序,由于复制的异步实现机制,同样会导致即使在晚做的修改也可能会被早做的修改所覆盖,就像如下情形: 时间点 Mysql A Mysql B 1 更新x表y记录为10 2 更新x表y记录为20 3 获取到A日志并应用,更新x表的y记录为10(不符合期望) 4 获取B日志更新x表y记录为20(符合期望) 这样,不仅在B库上面的数据不是用户所期望的结果,A和B两边的数据也出现了不一致的情况。除非能将写操作根据某种条件固定分开在A和B两端,保证不会交叉写入,才能够避免上面的问题。 本文转自 zouqingyun 51CTO博客,原文链接:http://blog.51cto.com/zouqingyun/1674074,如需转载请自行联系原作者

优秀的个人博客,低调大师

Mysql 复制原理以及配置 简要分析

这个图是我根据自己的理解将Mysql的主从复制的流程给画了出来,关于什么是Mysql主从复制技术,这里简单说一下。 有一次去一家刚刚成立的游戏公司面试,面试官问用过Mysql主从技术吗?我说:用过,我在产品中使用了双主复制。然后他质疑:复制是什么?不是都说主从吗? 然后我就石化了,他可能只听过主从,却不知复制,这里阐述 一下,主从表示的是架构类型,主服务器跟从服务器,而复制是实现这种架构的技术,不管是主从,还是主主都是Mysql的复制技术实现的。一个是服务器架构层面,一个是技术层面,这是个插曲。 使用场景: 数据库数据做冗余策略 / 数据库读写过于频繁,用于读写分离 架构类型:主从,主主,一主多从,双主多从,环形复制 等 配置复杂:不复杂 :) 好了,现在来简单描述一下上图的流程。 首先需要做复制,必备条件:主服务器开启二进制日志[binlog]功能(主从架构中,从服务器不用开启二进制日志功能) 二进制日志文件主要用于存放对数据产生了影响的语句,对数据未产生影响的,比如select查询语句是不会被记录下来的,如果需要对数据库进行优化操作,有必要找出需要优化的SQL查询语句,则开启慢查询日志,用于记录性能低下的SQL语句(keystone先生 如果看到这边注意下吧: )) 从服务器上面有个中继日志[relay-log] 以及两个线程(I/O线程以及SQL线程),当主服务器上面的数据发生了变化,二进制日志文件会记录相应的SQL语句,从服务器然后通过I/O线程请求并接受主服务器其的二进制日志文件内容,记录到本地的中继日志中,最后通过SQL线程将中继日志中的SQL语句再次执行,由此保证本地的数据跟主服务器一致。 以上就是主从复制的一个大概流程,也可以看出,复制的时候并不是主服务器的数据发生变化后,从服务器上的数据立即同步的,中间总会有这样的过程,所以复制技术被定义为:异步复制。所以复制只能从最大程度上面保证主从服务器的数据 ,而并不能完全保证,所以后来出现了“半同步复制技术”,特别是在一主多从复制中用的比较广泛,旨在保证至少一台从服务器跟主服务器完全一致。 那么什么是“半同步复制”呢? 听名字半同步也就知道肯定还是异步了,其实这个半同步复制个人觉得跟什么异步复制特性关系不大了,也应该从架构上面去分析,半同步复制指的是:主服务器必须保证其一个从服务器的中继日志完整之后才会提交操作,然后将数据从日志文件中写入磁盘。 现在简单说下如何配置Mysql的主从复制吧(mysql版本最好保证一致性或者从服务器高于主服务器) 1.安装主从服务器Mysql (版本5.6.11) 主服务器信息: [root@master ~]# hostname --fqdn master.clovem.com [root@master ~]# ip addr show eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 52:54:00:a7:b7:56 brd ff:ff:ff:ff:ff:ff inet 192.168.3.176/24 brd 192.168.3.255 scope global eth0 inet6 fe80::5054:ff:fea7:b756/64 scope link valid_lft forever preferred_lft forever 从服务器信息: root@slave ~]# hostname --fqdn slave.clovem.com [root@slave ~]# ip addr show eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 52:54:00:63:dd:89 brd ff:ff:ff:ff:ff:ff inet 192.168.3.130/24 brd 192.168.3.255 scope global eth0 inet6 fe80::5054:ff:fe63:dd89/64 scope link valid_lft forever preferred_lft forever 检查依赖包,开始安装mysql软件: [root@master ~]# rpm -q gcc gcc-c++ make cmake ncurses-devel bison gcc-4.4.6-4.el6.x86_64 gcc-c++-4.4.6-4.el6.x86_64 make-3.81-20.el6.x86_64 cmake-2.6.4-5.el6.x86_64 ncurses-devel-5.7-3.20090208.el6.x86_64 bison-2.4.1-5.el6.x86_64 [root@master ~]# cd mysql-5.6.11 [root@master mysql-5.6.11]# cmake . \ -DCMAKE_INSTALL_PREFIX=/usr/local/mysql/ \ -DWITH_INNOBASE_STORAGE_ENGINE=1\ -DENABLED_LOCAL_INFILE=1\ -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 \ -DDEFAULT_COLLATION=utf8_general_ci -DWITH_DEBUG=0 [root@master mysql-5.6.11]#make ; make install 主要参数解释:-DCMAKE_INSTALL_PREFIX=/usr/local/mysql/ 指定安装路径 -DWITH_INNOBASE_STORAGE_ENGINE=1 启用INNODB存储引擎 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 允许所有字符集,默认字符集为utf8 -DDEFAULT_COLLATION=utf8_general_ci 指定字符校验规则为utf8_general_ci 2. 安装结束,初始化系统数据: [root@master ~]# useradd mysql [root@master ~]# mkdir /data [root@master ~]# chown mysql.mysql /data/ [root@master ~]# /usr/local/mysql/scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql/ --datadir=/data 3. 修改配置文件以及添加启动脚本: [root@master ~]# cat /etc/my.cnf [mysqld] port=3306 user=mysql basedir=/usr/local/mysql datadir=/data socket=/data/mysql.sock pid-file=/data/mysql.pid log-bin=master-bin server-id=10 slave节点配置文件,主要区别server-id=11,数值需要大于主节点,优先级低 [root@slave ~]# cat /etc/my.cnf [mysqld] port=3306 user=mysql basedir=/usr/local/mysql datadir=/data socket=/data/mysql.sock pid-file=/data/mysql.pid log-bin=slave-bin server-id=11 配置启动脚本: [root@slave ~]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld [root@slave ~]# chmod +x /etc/init.d/mysqld [root@slave ~]#chkconfig --add mysqld [root@slave ~]#chkconfig mysqld on //设为开机启动 4. 启动mysql [root@master ~]# service mysqld start Starting MySQL SUCCESS! [root@master ~]# ps -ef |grep mysql root 10903 1 0 06:01 pts/0 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data --pid-file=/data/mysql.pid mysql 11110 10903 0 06:01 pts/0 00:00:01 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/master.clovem.com.err --pid-file=/data/mysql.pid --socket=/data/mysql.sock --port=3306 [root@slave ~]# service mysqld start Starting MySQL.. [ OK ] [root@slave ~]# ps -ef |grep mysql root 31033 1 1 14:12 pts/0 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data --pid-file=/data/mysql.pid mysql 31238 31033 7 14:12 pts/0 00:00:00 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/slave.clovem.com.err --pid-file=/data/mysql.pid --socket=/data/mysql.sock --port=3306 5.创建具备复制权限的用户rep_slave [root@master ~]# mysql -S /data/mysql.sock Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.6.11-log Source distribution Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO rep_slave@'slave.clovem.com' IDENTIFIED BY 'slave123456'; Query OK, 0 rows affected (0.01 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) mysql> QUIT Bye 6.验证用户是否创建成功 [root@slave ~]# mysql -urep_slave -pslave123456 -hmaster.clovem.com Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.6.11-log Source distribution Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> SHOW GRANTS; +---------------------------------------------------------------------------------------------------------------------------------------------------------+ | Grants for rep_slave@slave.clovem.com | +---------------------------------------------------------------------------------------------------------------------------------------------------------+ | GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'rep_slave'@'slave.clovem.com' IDENTIFIED BY PASSWORD '*F30CB7DBFF2ADA396886C76E18C15F6B8AE108C8' | +---------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> QUIT Bye 7.记录主服务器当前二进制日志文件信息 (1)查看二进制日志文件功能是否开启 (2)对所有的表加读锁,不可以写入数据【没有配置完成之前退出该mysql终端】 (3)查看当前二进制日志文件信息:当前二进制日志文件名[master-bin.000002]以及位置[437] [root@master ~]# mysql -S /data/mysql.sock Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 6 Server version: 5.6.11-log Source distribution Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> FLUSH TABLES WITH READ LOCK; Query OK, 0 rows affected (0.00 sec) mysql> SHOW VARIABLES LIKE '%log_bin%'; +---------------------------------+------------------------+ | Variable_name | Value | +---------------------------------+------------------------+ | log_bin | ON | | log_bin_basename | /data/master-bin | | log_bin_index | /data/master-bin.index | | log_bin_trust_function_creators | OFF | | log_bin_use_v1_row_events | OFF | | sql_log_bin | ON | +---------------------------------+------------------------+ 6 rows in set (0.00 sec) mysql> SHOW MASTER STATUS; +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000002 | 437 | | | | +-------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> 8. 指向主服务器 [root@slave ~]# mysql -S /data/mysql.sock Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.6.11-log Source distribution Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> CHANGE MASTER TO -> MASTER_HOST='master.clovem.com', -> MASTER_USER='rep_slave', -> MASTER_PASSWORD='slave123456', -> MASTER_PORT=3306, -> MASTER_LOG_FILE='master-bin.000002', -> MASTER_LOG_POS=437; Query OK, 0 rows affected, 2 warnings (0.36 sec) mysql> START SLAVE; Query OK, 0 rows affected (0.04 sec) mysql> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: master.clovem.com Master_User: rep_slave Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000002 Read_Master_Log_Pos: 437 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 284 Relay_Master_Log_File: master-bin.000002 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 437 Relay_Log_Space: 457 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 10 Master_UUID: 0a2335d4-ce2b-11e2-bde9-525400a7b756 Master_Info_File: /data/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 1 row in set (0.00 sec) mysql> 成功标志: Slave_IO_Running: Yes Slave_SQL_Running: Yes 这两个线程就是上文所说的读取二进制日志,写中继日志的I/O进程 以及将中继日志中的SQL语句执行成功的SQL进程 状态均为YES,基本表明配置成功。 9.在主服务器上面创建数据进行测试 mysql> UNLOCK TABLES; Query OK, 0 rows affected (0.00 sec) mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 4 rows in set (0.00 sec) mysql> CREATE DATABASE clovemdb; Query OK, 1 row affected (0.00 sec) mysql> USE clovemdb; Database changed mysql> CREATE TABLE t1(id INT, name VARCHAR(10)); Query OK, 0 rows affected (0.20 sec) mysql> INSERT INTO t1 SELECT 1,'clovemfong'; Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> INSERT INTO t1 SELECT 2,'wanghao'; Query OK, 1 row affected (0.03 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> INSERT INTO t1 SELECT 3,'lichunfeng'; Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT COUNT(*) FROM t1; +----------+ | COUNT(*) | +----------+ | 3 | +----------+ 1 row in set (0.00 sec) mysql> SELECT * FROM t1; +------+------------+ | id | name | +------+------------+ | 1 | clovemfong | | 2 | wanghao | | 3 | lichunfeng | +------+------------+ 3 rows in set (0.00 sec) mysql> 10.在从服务器上面验证数据是否同步 注意:由于没有在配置文件中指定需要复制的数据库或者表,默认复制主服务器上面的全部库以及表数据 [root@slave ~]# mysql -S /data/mysql.sock -e "SHOW DATABASES;" +--------------------+ | Database | +--------------------+ | information_schema | | clovemdb | | mysql | | performance_schema | | test | +--------------------+ [root@slave ~]# mysql -S /data/mysql.sock clovemdb -e "SHOW TABLES;" +--------------------+ | Tables_in_clovemdb | +--------------------+ | t1 | +--------------------+ [root@slave ~]# mysql -S /data/mysql.sock clovemdb -e "SELECT * FROM t1;" +------+------------+ | id | name | +------+------------+ | 1 | clovemfong | | 2 | wanghao | | 3 | lichunfeng | +------+------------+ 通过上面的步骤可以成功配置两台mysql服务器为主从架构了,希望大家成功! 下面贴出一些生产环境中一些问题棘手问题的参数: slave-skip-errors=all //该参数用来跳过所有SQL报错的,一般情况下面,如果复制过程中发生了语句报错信息,比如主服务器删除一个有外键的表数据,结果删除失败,这个时候整个复制都会终止,就需要重新启动slave进程,如果对自己的产品中的语句信心没那么大的话,建议加上此参数,否则在主服务器宕机之后,你会很悲剧的发现原来从服务器没有最新数据! log-slave-updates //这个参数比较有意思了,这边暂时不阐述,后面有机会写双主多从的时候再去涉及,作用是非常大滴。 replicate-do-db = clovemdb //这个参数用于定义需要复制的数据库,指定之后就不会复制所有的库了 auto-increment-increment = 2 auto-increment-offset = 1 //以上两个 参数是在配置主主复制的时候使用的,主要防止自动增长列发生重复 auto-increment-increment 该参数的值是定义“步长”,一般设置为主节点的个数,主主复制就是2 auto-increment-offset 该参数的值是定义初始化值,从1到主节点个数最大值。 本文转自 暗黑魔君 51CTO博客,原文链接:http://blog.51cto.com/clovemfong/1217103,如需转载请自行联系原作者

优秀的个人博客,低调大师

Ophone平台便捷呼叫功能实现原理

在OPhone平台上,捕获用户在界面上的触发事件有很多种方法。一般来讲,开发者会从用户交互的特定的View对象(例如Button、TextView等)中捕捉事件,并使用View类提供方法来实现。前文中我们分析了软件的第一个功能的构成形式,在界面方面,由按钮和菜单两部分组成,初始化代码如下: public class CallAST extends Activity implements OnClickListener{ private Button btn1, btn2,btn3; private TextView tv; private EditText edit1,edit2; private SharedPreferences contact; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); btn1 = (Button)findViewById(R.id.Button01); btn2 = (Button)findViewById(R.id.Button02); btn3 = (Button)findViewById(R.id.Button03); contact = getSharedPreferences("contact",0); btn1.setText(contact.getString("Button01name","")); btn2.setText(contact.getString("Button02name","")); btn3.setText(contact.getString("Button03name","")); tv = (TextView)findViewById(R.id.TextView01); btn1.setOnClickListener(this); btn2.setOnClickListener(this); btn3.setOnClickListener(this); } 上述代码在界面上添加3个按钮,并从SharedPreferences中读取按钮的标题。菜单用于实现按钮标题的修改,采用BT1、BT2、BT3的菜单名称分别对应3个按钮。代码如下: @Override public boolean onCreateOptionsMenu(Menu menu) { int i; for(i=1;i<=3;i++) menu.add(0,i,i,"BT"+Integer.toString(i)); return super.onCreateOptionsMenu(menu); } 在上述代码中,与以往程序最大的不同之处在于:在Class的声明中多了implements OnClickListener。根据MVC模式的设想,该功能用于实现(implements)单击响应的接口(interface)。在单击按钮时,软件呼叫该按钮对应的联系人号码。它的定义是: abstract void onClick(View v) 代码如下: public void onClick(View arg0) { String callnum=""; contact = getSharedPreferences("contact",0); if (arg0==btn1) callnum = contact.getString("Button01num",""); if (arg0==btn2) callnum = contact.getString("Button02num",""); if (arg0==btn3) callnum = contact.getString("Button03num",""); if (!(callnum.equals(""))) startActivity(new Intent( Intent.ACTION_CALL, Uri.parse("tel:"+callnum))); } 知识点:Event Listener和Event Hanlder 当相应的事件在该对象上发生时,这些方法被OPhone的框架所呼叫。例如:当一个View(如一个Button)被单击,onTouchEvent方法会在该对象上被调用,为了响应该事件,我们必须extend该Class,并且override这个方法。这就是View类还包含一系列通用接口和回调的原因,以便于用户可以统一地定义和管理。这些接口(例如上面代码中的OnClickListener接口),就称为event listener,是我们捕捉用户行为的工具。 当我们使用event listener来监听用户行为时,如果确实有需要extend一个view来建立一个特定的组件,在这种情况下,你可以使用event handler来为该class定义默认的事件行为,如onKeyDown、onKeyUp、onTouchEvent、onTrackballEvent、onFocusChanged。 弹出对话框 在此之前的所有代码,都是从SharedPreferences中取出数据(按钮标题和呼叫号码),但是我们还没有看到写入数据的过程——在菜单中编辑SharedPreferences的数据。在单击菜单时,软件弹出窗口,用户在弹出的窗口中输入标题和呼叫号码。Windows使用Messagebox函数来管理对话框,在OPhone中,需要使用AlertDialog.Builder来建立对话框并实现数据的提交。在onCreate中需要新建AlertDialog.Builder对象,代码如下: builder = new AlertDialog.Builder(this); @Override public boolean onOptionsItemSelected(MenuItem item) { final int itid = item.getItemId(); LinearLayout layout = new LinearLayout(CallAST.this); //新建对话框布局用于放置文本框和按钮 layout.setOrientation(LinearLayout.VERTICAL); //设置控件走向 LinearLayout.LayoutParams param = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); edit1 = new EditText(CallAST.this); edit2 = new EditText(CallAST.this); layout.addView(edit1, param); //在layout上添加文本框 layout.addView(edit2, param); builder.setView(layout); //将layout和对话框相关联 builder.setPositiveButton("OK",new DialogInterface.OnClickListener() { @Override //添加OK按钮及其响应 public void onClick(DialogInterface arg0, int arg1) { writetosp(itid,edit1.getText().toString(), edit2.getText().toString());} //将按钮标题和呼叫号码写入后台配置文件 }); builder.show(); return super.onOptionsItemSelected(item); } 保存输入数据 在弹出窗口的代码中,我们对LinearLayout很熟悉,因为在main.xml的界面描述中,layout是不可缺少的元素。但是在这里,layout是作为一个界面对象存在的,开发者对layout对象进行初始化和编辑,并将其视图(View)显示在builder上。我们在前文中提到,builder是一个对话框管理器,负责对话框的界面和按钮响应。对话框的“OK”按钮调用了一个叫做writetosp的方法,该方法将对话框中的数据写入SharedPreferences,供按钮的标题和呼叫响应提取。代码如下: private void writetosp(int spid,String name,String num){ contact = getSharedPreferences("contact",0); contact.edit().putString("Button0"+Integer.toString(spid)+ "name",name).commit(); contact.edit().putString("Button0"+Integer.toString(spid)+ "num",num).commit(); switch(spid){ case 1:{ btn1.setText(name); break; } case 2:{ btn2.setText(name); break; } case 3:{ btn3.setText(name); break; } }} 上述代码将每个按键的参数,如Button01name、Button01num的形式存入SharedPreferences。在写入按键参数之后,后台的数据发生了变化,但是按钮的标题并没有更新,所以需要在后面的switch-case部分,实时更新按钮标题。在输入以上代码后,第一个功能基本完成,运行效果如图4-7所示,单击“张三”后,程序出现错误。 如何使用permission 在Debug视图中查看日志,可以看到一大串的错误信息,第一条是Permission Denial:starting Intent{action=android.intent.action. CALL data=tel: 13912345678 comp={com.android.phone/com.android.phone.InCallScreen}} from ProcessRecord{43bc7a20 1601:oms.CallAST/10040}(pid=1601,uid= 10040)requires android.permission.CALL_PHONE,如图4-8所示。 日志跟踪结果中指出:“系统不允许呼叫,需要许可证(Permission)—android. permission.CALL_PHONE”。那究竟什么是系统允许的操作,什么是系统禁止的操作?这就要涉及OPhone系统的安全许可机制。OPhone系统在默认的情况下,应用程序不允许访问可能影响操作系统或者其他应用程序的API。这些API都是敏感操作,如访问语音网络、数据网络、访问硬件等。如果开发者希望程序访问这些敏感API,必须在AndroidManifest.xml中添加请求。对于用户来说,在安装该软件时,系统会显示出敏感API的列表,可以使用户看到该软件对系统的影响,并选择是否继续安装。这和手机Java平台不同,J2ME在安装时不作提示,但是在运行时,例如访问网络时会弹出对话框询问是否允许访问网络。OPhone在程序安装时就设置好规则,让用户在使用时具备更好的体验。 为了让系统允许呼叫操作,开发者需要在AndroidManifest.xml的permissions选项卡中添加安全许可,如图4-9所示。 单击“Add”按钮,选择“Uses Permission”,如图4-10所示。在右侧下拉列表中选择android.permission. CALL_PHONE,完成安全许可的添加,如图4-11所示。在AndroidManifest.xml文件的文本标签中可以看到文件多了一行“Uses Permission”。 知识点:常用Permission列举 l ACCESS_FINE_LOCATION:精确位置信息获取,如GPS应用等。 l ACCESS_NETWORK_STATE/CHANGE_NETWORK_STATE:获取/改变网络状态信息。 l ACCESS_WIFI_STATE/CHANGE_WIFI_STATE:获取/改变WiFi等WLAN无线网络的状态。 l RECEIVE_MMS/RECEIVE_SMS/SEND_SMS:收彩信,收发短信。 l BATTERY_STATS:获取Android平台上电池设备信息。 l CAMERA:摄像头权限控制。 l INTERNET:访问网络。 完成Permission的添加之后,再次运行程序,单击“张三”按钮,可以看到软件界面切换至拨号界面,电话被拨出,如图4-12所示。在OPhone中,一个应用程序的进程就是一个安全的沙盒。它不能干扰其他应用程序,除非显式地声明了“Permissions”,以便它能够获取基本沙盒所不具备的额外的能力。它请求的这些权限“Permissions”可以被各种各样的操作处理,如自动允许该权限或者通过用户提示或者证书来禁止该权限。应用程序需要的那些“Permissions”是静态的,在程序中声明,所以他们会在程序安装时就被知晓,并不会再改变。 知识点:什么是沙盒? 沙盒(Sandbox,也称为沙箱)是一种容器,所谓容器,也就是通过某种保护层之类的东西与外界隔离开。在军事上,人们常用沙盒按照一定的比例制作地形模型以及放置代表军队与武器布置的模型或图案,不用了可将沙子推倒重来。在现在的计算机领域中,沙盒是一种安全软件,可以将一个程序放入沙盒运行,这样它所创建、修改、删除的所有文件和注册表都会被虚拟化重定向,也就是说所有操作都是虚拟的,真实的文件和注册表不会被改动,这样可以确保病毒无法对系统关键部位进行改动而破坏系统。 本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/wws5201985/817462,如需转载请自行联系原作者

优秀的个人博客,低调大师

Docker核心原理-资源隔离和限制

通常情况运行docker容器没有指定具体哪个cpu和内存的分配,其实docker官方给出了,docker容器可以运行在指定CPU上通过docker run --help可以看到: 先制作docker镜像: 编写Dockerfile 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 [root@linux-node1~] #cdstress/ [root@linux-node1stress] #catDockerfile FROMcentos ADDepel-6.repo /etc/yum .repos.d/ RUNyum-y install stress&&yumcleanall ENTRYPOINT[ "stress" ] [root@linux-node1stress] # [root@linux-node1stress] #dockerbuild-tstress. SendingbuildcontexttoDockerdaemon4.096kB Step1:FROMcentos --->970633036444 Step2:ADDepel-6.repo /etc/yum .repos.d/ --->77600d6b488e Removingintermediatecontainerf141f47cb34f Step3:RUNyum-y install stress&&yumcleanall --->Running in 0949035c73da Loadedplugins:fastestmirror,ovl http: //mirrors .aliyuncs.com /epel/6/x86_64/repodata/98697cba0d79c083725de0c38b11c15878b35f5e27262becc02cd7ed1a13ac22-updateinfo .xml.bz2:[Errno12]Timeoutonhttp: //mirrors .aliyuncs.com /epel/6/x86_64/repodata/98697cba0d79c083725de0c38b11c15878b35f5e27262becc02cd7ed1a13ac22-updateinfo .xml.bz2:(28, 'Connectiontimedoutafter30001milliseconds' ) Tryingothermirror. Determiningfastestmirrors *base:mirrors.zju.edu.cn *epel:mirrors.aliyun.com *extras:mirrors.zju.edu.cn *updates:mirrors.cqu.edu.cn ResolvingDependencies -->Runningtransactioncheck --->Packagestress.x86_640:1.0.4-4.el6willbeinstalled -->FinishedDependencyResolution DependenciesResolved ================================================================================ PackageArchVersionRepositorySize ================================================================================ Installing: stressx86_641.0.4-4.el6epel36k TransactionSummary ================================================================================ Install1Package Totaldownloadsize:36k Installedsize:89k Downloadingpackages: Runningtransactioncheck Runningtransaction test Transaction test succeeded Runningtransaction Installing:stress-1.0.4-4.el6.x86_641 /1 install -info:Nosuch file ordirectory for /usr/share/info/stress .info Verifying:stress-1.0.4-4.el6.x86_641 /1 Installed: stress.x86_640:1.0.4-4.el6 Complete! Loadedplugins:fastestmirror,ovl Cleaningrepos:baseepelextrasupdates Cleaningupeverything Cleaninguplistoffastestmirrors --->504c747b9b51 Removingintermediatecontainer0949035c73da Step4:ENTRYPOINTstress --->Running in ea8d8eb8fb87 --->7e1e0e5cf825 Removingintermediatecontainerea8d8eb8fb87 Successfullybuilt7e1e0e5cf825 [root@linux-node1stress] #dockerimages REPOSITORYTAGIMAGEIDCREATEDSIZE stresslatest7e1e0e5cf825Aboutaminuteago214MB ningx- file v01460b5af495c43daysago531.9MB nginx /ningx 1.9.3v02097c98e3cb2b3daysago534.6MB nginx1.9.3d2cfb9ed3f2b3daysago534.6MB docker.io /centos latest97063303644411daysago196.7MB [root@linux-node1stress] # 查看docker run命令帮助输出: 1 2 3 4 5 6 7 [root@linux-node1stress] #dockerrun--help|grepcpu --cpu-sharesCPUshares(relativeweight) --cpu-periodLimitCPUCFS(CompletelyFairScheduler)period --cpu- quota LimitCPUCFS(CompletelyFairScheduler) quota --cpuset-cpusCPUs in which toallowexecution(0-3,0,1) --cpuset-memsMEMs in which toallowexecution(0-3,0,1) [root@linux-node1stress] # 启动一个容器: 1 2 [root@linux-node1stress] #dockerrun-it--rm--cpuset-cpus=0stress--cpu1 stress:info:[1]dispatchinghogs:1cpu,0io,0vm,0hdd 在另外一个窗口查看使用情况cpu: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [root@linux-node1~] #top top -00:55:15up13:39,2 users ,loadaverage:0.58,0.47,0.69 Tasks:406total,2running,404sleeping,0stopped,0zombie %Cpu0:100.0us,0.0sy,0.0ni,0.0 id ,0.0wa,0.0hi,0.0si,0.0st %Cpu1:0.3us,0.3sy,0.0ni,99.3 id ,0.0wa,0.0hi,0.0si,0.0st %Cpu2:0.0us,0.0sy,0.0ni,100.0 id ,0.0wa,0.0hi,0.0si,0.0st %Cpu3:0.0us,0.0sy,0.0ni,100.0 id ,0.0wa,0.0hi,0.0si,0.0st KiBMem:773004total,204488 free ,194528used,373988buff /cache KiBSwap:2098172total,2096324 free ,1848used.399644availMem PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND 5944root2007260920R100.00.00:52.46stress 335root200000S0.30.01:17.95kworker /3 :1 1569root200553044136242952S0.31.80:13.46tuned 4779root200000S0.30.00:02.25kworker /1 :1 5946root20015794825041548R0.30.30:00.18 top 同样,再开启一个窗口: 1 2 [root@linux-node1stress] #dockerrun-it--rmstress--cpu1 stress:info:[1]dispatchinghogs:1cpu,0io,0vm,0hdd 再查切换到其他窗口查看cpu使用情况 1 2 3 4 5 6 7 8 9 10 [root@linux-node1~] #top top -00:57:52up13:41,3 users ,loadaverage:1.50,0.96,0.84 Tasks:414total,2running,412sleeping,0stopped,0zombie %Cpu0:100.0us,0.0sy,0.0ni,0.0 id ,0.0wa,0.0hi,0.0si,0.0st %Cpu1:0.0us,0.0sy,0.0ni,100.0 id ,0.0wa,0.0hi,0.0si,0.0st %Cpu2:0.0us,0.0sy,0.0ni,100.0 id ,0.0wa,0.0hi,0.0si,0.0st %Cpu3:0.0us,2.7sy,0.0ni,97.3 id ,0.0wa,0.0hi,0.0si,0.0st KiBMem:773004total,195560 free ,199560used,377884buff /cache KiBSwap:2098172total,2096576 free ,1596used.393660availMem PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND 注意命令: docker run -it --rm stress --cpu 1 docker run -it --rm --cpuset-cpus=0 stress --cpu 1 --cpuset-cpus后面跟cpu总个数,为docker容器指定的,而--cpu是用多少个cpu来运行,只能是1、2、3、4 ...N等等 本文转自027ryan 51CTO博客,原文链接:http://blog.51cto.com/ucode/1836484,如需转载请自行联系原作者

优秀的个人博客,低调大师

ArangoDB介绍——未知架构和底层原理

ArangoDB介绍 ArangoDB是一个开源NoSQL数据库,官网:https://www.ArangoDB.org/ ArangoDB支持灵活的数据模型,比如文档Document、图Graph以及键值对Key-Value存储。ArangoDB同时也是一个高性能的数据库,它使用类SQL查询或JavaScript扩展来构建高性能应用。 ArangoDB值得称赞的一点,可以在树莓派上运行ArangoDB 1.4版。 ArangoDB的特性: 1)多模型数据库 可以灵活的使用键值对、文档、图及其组合构建你的数据模型。 2)查询便利 ArangoDB有类SQL的AQL查询语言,还可以通过REST方式进行查询。 3)可通过JavaScript进行扩展 无语言范围的限制,可以从前端到后端都使用同一种语言。 4)高性能 ArangoDB速度极快 5)Foxx - 构建自己的API 用JavaScript和ArangoDB构建应用,Foxx运行在DB内部,可快速访问数据。 6)空间利用率高 跟其它文档型数据库相比,ArangoDB占用的存储空间更少,因为ArangoDB是模式自由的元数据模式。 7)简单易用 ArangoDB可以在几秒内启动运行,同时可使用图形界面来管理你的ArangoDB。 8)多OS支持 ArangoDB支持Windows、Linux和OSX等操作系统,还支持树莓派。 9)开源且免费 ArangoDB开源免费,它采用了Apache 2许可证协议。 10)复制 ArangoDB支持主从集群 简单说下Aerospike的安装,我这边有个服务器是Ubuntu的,那就用它了。 如果有Docker的话,那敢情好了。直接下载image,run一下就好了。 wget -O aerospike.tgz 'http://aerospike.com/download/server/latest/artifact/ubuntu12' tar -xvf aerospike.tgz cd aerospike-server-community-*-ubuntu12 sudo ./asinstall # will install the .rpm packages sudo service aerospike start && \ sudo tail -f /var/log/aerospike/aerospike.log | grep cake 有时候自己手动启动。 sudo /etc/init.d/aerospike start 另外大家可以学习下python的aerospike库。Python # import the module import aerospike # Configuration for the client config = { 'hosts': [ ('127.0.0.1', 3000) ] } # Create a client and connect to the database client = aerospike.client(config).connect() # Records are addressable via a tuple of (namespace, set, key) key = ('test', 'demo', 'foo') # Write a record client.put(key, { 'name': 'John Doe', 'age': 32 }) # Read a record (key, metadata, record) = client.get(key) # Close Connection to Cluster client.close() 性能比较见http://www.infoq.com/cn/news/2013/04/NoSQL-Benchmark 整体看来 如果是充分利用内存提速的话 要比mongodb好! 本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/bonelee/p/6244006.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android面试,IntentService的原理及使用

在Android开发中,我们或许会碰到这么一种业务需求,一项任务分成几个子任务,子任务按顺序先后执行,子任务全部执行完后,这项任务才算成功。那么,利用几个子线程顺序执行是可以达到这个目的的,但是每个线程必须去手动控制,而且得在一个子线程执行完后,再开启另一个子线程。或者,全部放到一个线程中让其顺序执行。这样都可以做到,但是,如果这是一个后台任务,就得放到Service里面,由于Service和Activity是同级的,所以,要执行耗时任务,就得在Service里面开子线程来执行。那么,有没有一种简单的方法来处理这个过程呢,答案就是IntentService。 什么是IntentService,IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们去手动控制。另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。 所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread),同一时间只处理一个请求。 那么,用IntentService有什么好处呢?首先,我们省去了在Service中手动开线程的麻烦,第二,当操作完成时,我们不用手动停止Service。 Code 接下来让我们来看看如何使用,我写了一个Demo来模拟两个耗时操作,Operation1与Operation2,先执行1,2必须等1执行完才能执行: 新建工程,新建一个继承IntentService的类,我这里是IntentServiceDemo.java public class IntentServiceDemo extends IntentService { public IntentServiceDemo() { //必须实现父类的构造方法 super("IntentServiceDemo"); } @Override public IBinder onBind(Intent intent) { System.out.println("onBind"); return super.onBind(intent); } @Override public void onCreate() { System.out.println("onCreate"); super.onCreate(); } @Override public void onStart(Intent intent, int startId) { System.out.println("onStart"); super.onStart(intent, startId); } @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public void setIntentRedelivery(boolean enabled) { super.setIntentRedelivery(enabled); System.out.println("setIntentRedelivery"); } @Override protected void onHandleIntent(Intent intent) { //Intent是从Activity发过来的,携带识别参数,根据参数不同执行不同的任务 String action = intent.getExtras().getString("param"); if (action.equals("oper1")) { System.out.println("Operation1"); }else if (action.equals("oper2")) { System.out.println("Operation2"); } try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void onDestroy() { System.out.println("onDestroy"); super.onDestroy(); } } 我把生命周期方法全打印出来了,待会我们来看看它执行的过程是怎样的。接下来是Activity,在Activity中来启动IntentService: public class TestActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //可以启动多次,每启动一次,就会新建一个work thread,但IntentService的实例始终只有一个 //Operation 1 Intent startServiceIntent = new Intent("com.test.intentservice"); Bundle bundle = new Bundle(); bundle.putString("param", "oper1"); startServiceIntent.putExtras(bundle); startService(startServiceIntent); //Operation 2 Intent startServiceIntent2 = new Intent("com.test.intentservice"); Bundle bundle2 = new Bundle(); bundle2.putString("param", "oper2"); startServiceIntent2.putExtras(bundle2); startService(startServiceIntent2); } } 最后,别忘了配置Service,因为它继承于Service,所以,它还是一个Service,一定要配置,否则是不起作用的,开始我就是忘了,结果半天没反应。 <service android:name=".IntentServiceDemo"> <intent-filter > <action android:name="com.test.intentservice"/> </intent-filter> </service> 最后来看看执行结果: 从结果可以看到,onCreate方法只执行了一次,而onStartCommand和onStart方法执行了两次,开启了两个Work Thread,这就证实了之前所说的,启动多次,但IntentService的实例只有一个,这跟传统的Service是一样的。Operation1也是先于Operation2打印,并且我让两个操作间停顿了2s,最后是onDestroy销毁了IntentService。 我是天王盖地虎的分割线 本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/3960886.html,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册