首页 文章 精选 留言 我的

精选列表

搜索[基础搭建],共10000篇文章
优秀的个人博客,低调大师

kafka基础集群部署

kafka集群部署方案 ZooKeeper 第一步主机名称到IP地址映射配置 ZooKeeper集群中具有两个关键的角色Leader和Follower。集群中所有的结点作为一个整体对分布式应用提供服务集群中每个结点之间都互相连接所以在配置的ZooKeeper集群的时候每一个结点的host到IP地址的映射都要配置上集群中其它结点的映射信息。例如我的ZooKeeper集群中每个结点的配置以zk-01为例/etc/hosts内容如下所示: 192.168.0.11 zk-01 192.168.0.12 zk-02 192.168.0.13 zk-03 第二步配置更改配置文件 ZooKeeper采用一种称为Leader election的选举算法。在整个集群运行过程中只有一个Leader其他的都是Follower如果ZooKeeper集群在运行过程中Leader出了问题系统会采用该算法重新选出一个Leader。因此各个结点之间要能够保证互相连接必须配置上述映射。ZooKeeper集群启动的时候会首先选出一个Leader在Leader election过程中某一个满足选举算的结点就能成为Leader。整个集群的架构可以参考http://zookeeper.apache.org/doc/trunk/zookeeperOver.html#sc_designGoals。第二步修改ZooKeeper配置文件在其中一台机器zk-01上解压缩zookeeper-3.3.4.tar.gz修改配置文件conf/zoo.cfg内容如下所示 tickTime=2000 dataDir=/home/hadoop/storage/zookeeper clientPort=2181 initLimit=5 syncLimit=2 server.1=zk-01:2888:3888 server.2=zk-02:2888:3888 server.3=zk-03:2888:3888 第三步远程复制分发安装文件上面已经在一台机器zk-01上配置完成ZooKeeper现在可以将该配置好的安装文件远程拷贝到集群中的各个结点对应的目录下 scp -r zookeeper-3.3.4/ shirdrn@zk-02:/home/hadoop/installation/ scp -r zookeeper-3.3.4/ shirdrn@zk-03:/home/hadoop/installation/ 第四步设置myid在我们配置的dataDir指定的目录下面创建一个myid文件里面内容为一个数字用来标识当前主机conf/zoo.cfg文件中配置的server.X中X为什么数字则myid文件中就输入这个数字例如 建立data目录 mkdir -pv /home/hadoop/storage/zookeeper shirdrn@zk-01:~/installation/zookeeper-3.3.4$ echo "1" > /home/hadoop/storage/zookeeper/myid shirdrn@zk-02:~/installation/zookeeper-3.3.4$ echo "2" > /home/hadoop/storage/zookeeper/myid shirdrn@zk-03:~/installation/zookeeper-3.3.4$ echo "3" > /home/hadoop/storage/zookeeper/myid 启动zookeeper服务, 分别在3个机器上zk_01zk_02zk_03: bin/zkServer.sh start 查看状态 bin/zkServer.sh status #####################################Kafka部署 一、安装Kafka wget http://apache.fayea.com/kafka/0.9.0.0/kafka_2.11-0.9.0.0.tgz wget http://apache.fayea.com/kafka/0.9.0.0/kafka_2.10-0.9.0.0.tgz wget http://apache.fayea.com/kafka/0.8.2.2/kafka_2.11-0.8.2.2.tgz wget http://apache.fayea.com/kafka/0.8.2.2/kafka_2.10-0.8.2.2.tgz wget http://apache.fayea.com/kafka/0.8.2.2/kafka_2.9.2-0.8.2.2.tgz wget http://apache.fayea.com/kafka/0.8.2.2/kafka_2.9.1-0.8.2.2.tgz # tar zxvf kafka_2.9.1-0.8.2.2.tgz -C /usr/local/ # cd /usr/local/kafka_2.9.1-0.8.2.2/ 二、我们安装3个broker分别在3个机器上zk_01zk_02zk_03:1、编辑zk_01 # vim config/server.properties broker.id=0 port=9092 zookeeper.connect=zk_01:2181,zk_02:2181,zk_03:2181 -------------------------------------------------------------- vim consumer.properties zookeeper.connect=zk-01:2181,zk-02:2181,zk-03:2181 ---------------------------------------------------------------- vim producer.properties metadata.broker.list=zk-01:9092,zk-02:9092,zk-03:9092 2、编辑zk_02 # vim config/server.properties 1 broker.id=1 2 port=9092 6 zookeeper.connect=zk_01:2181,zk_02:2181,zk_03:2181 -------------------------------------------------------------- vim consumer.properties zookeeper.connect=zk-01:2181,zk-02:2181,zk-03:2181 ---------------------------------------------------------------- vim producer.properties metadata.broker.list=zk-01:9092,zk-02:9092,zk-03:9092 3、编辑zk_03 # vim config/server.properties 1 broker.id=32 2 port=9092 6 zookeeper.connect=zk_01:2181,zk_02:2181,zk_03:2181 -------------------------------------------------------------- vim consumer.properties zookeeper.connect=zk-01:2181,zk-02:2181,zk-03:2181 ---------------------------------------------------------------- vim producer.properties metadata.broker.list=zk-01:9092,zk-02:9092,zk-03:9092 三、启动Kafka服务, 分别在3个机器上zk_01zk_02zk_03: nohup bin/kafka-server-start.sh config/server.properties & 测试 a.启动一个服务端 bin/kafka-server-start.sh config/server.properties b.查看topic bin/kafka-topics.sh --list --zookeeper localhost:2181 创建topic bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test 查看topic描述 bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic c.测试生产者写入信息消费者收到信息 启动一个生产者 bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test 开启一个消费者 bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic test --from-beginning http://my.oschina.net/lgscofield/blog/485004 http://xiaorui.cc 本文转自 msj0905 51CTO博客,原文链接:http://blog.51cto.com/sky66/1727532

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

Android基础之一

Android是当前灰常火爆的一个手机操作系统,前不久刚给老婆买了一个Android系统的手机,用起来,感觉很爽的说,比我的黑莓用的爽多了。手里有这么个机器之后,总想着在上面搞点什么自己的东西来,这个是程序员的通病了。于是,利用平常在公司的午休时间开始学习Android的开发。这里将记录,我学习的每一个步骤。 要开发,第一步自然是准备开发工具,网上的教程多数讲解的是用Eclipse做为开发工具,但是我本人不大喜欢它,相对而言,我比较喜欢Netbeans这个开发工具,所以我这里就选择了Netbeans。怎么布置Netbeans为Android的开发工具,我这里就不讲了,很简单的。添加一个他的Android的开发插件就行,更新地址在 http://kenai.com/downloads/nbandroid/updates.xml。之后就是下载Android的开发包,这个网上也有,下载好了之后,在Netbeans的平台设置中,把Android的平台信息都添加进去。之后可以新建一个Android工程。一个Android新建工程会默认生成几个文件 R.Java这个是资源文件的映射ID信息,可以通过本ID直接在程序中引用的。这个资源文件,默认会生成main.xml和strings.xml。 比如引用里面的信息可以R.string.ShowText//这个就是指定的Strings.xml文件中的ShowText的值 在xml中引用就可以直接"@string/ShowText"也表示用的Strings.xml的ShowText值 之后又一个Manifest.xml的文件,初步认为本文件是用来设置Android程序入口的配置, 代码 android:label这个指定为程序名,也就是呈现在手机中的名字标题显示 那么第一步,先在界面上显示文字,可以配置Main.xml 代码 代码 除此之外,还可以引用import android.widget.TextView;包,然后自己创建显示信息 TextView tv=new TextView(this); tv.setText(R.string.ShowText); setContentView(tv); 本文转自 不得闲 博客园博客,原文链接: http://www.cnblogs.com/DxSoft/archive/2011/01/07/1929690.html,如需转载请自行联系原作者

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

Docker基础配置简介

随着容器技术的发展,微服务架构被许多互联网公司推崇。docker作为一种容器的交付方式,可以实现快速交付,应用隔离,保持环境一致性等多方面的优点。这里对docker的操作做简单的介绍。 安装部署 docker的安装和配置非常简单,如果对版本没有要求在系统的默认镜像源中就有,可直接安装即可。 1 yum install docker-y 修改默认镜像源为国内的阿里镜像,使用阿里账号登录https://cr.console.aliyun.com 在"DockerHub镜像站点"中可以找到添加方式: 1 vim /usr/lib/systemd/system/docker .service 添加一行--registry-mirror的 1 ExecStart= /usr/bin/dockerd-current --registry-mirror=https: //qxx96o44 .mirror.aliyuncs.com\ 启动docker: 1 2 systemctldaemon-reload systemctlstartdocker 使用docker daemon --help 可以查看后台启动进程的一些可配置参数。 Docker 常用管理命令 镜像管理 对于docker我们可以通过本地导入镜像的方式,或者直接从网络上的镜像仓库进行下载。 显示镜像 docker images 搜索镜像 docker search nginx 下载镜像 docker pull nginx 导出镜像 docker save nginx > /tmp/nginx.tar.gz 导入镜像 docker load < /tmp/nginx.tar.gz 删除镜像 docker rmi nginx 命名镜像 docker tag image-id name:tag 容器管理 当下载好一个镜像之后,下一步就是使用这个镜像来启动一个容器,启动容器我们使用docker run 命令,这里会自动创建并启动。 启动一个容器,并进入终端, 退出后容器停止 1 dockerrun-itnginxsh #-i-t打开一个伪终端,打开标准输入,sh执行的命令 如果要想退出终端后容器不停止,可以使用 组合键:ctrl + p + q 或者登录容器使用 exec 命令(退出登录后容器不终止): 1 docker exec -itcon-namesh 也可以使用如下命令登录容器,但是与其他的登录者共享一个终端,能看到实时操作(退出会终止): 1 dockerattachCon-name 如果你看不见shell提示符,按键盘方向键的上箭头。 启动容器,命名为test,并让其在后台运行: 1 dockerrun-d--name test centos bash -c "fornin{1..10};doechoup;sleep1;done" 可以使用docker logs 查看容器的运行状态信息: 1 2 dockerlogs test dockerlogs test -f #实时查看日志 启动一个容器,命名为mynginx,退出后容器删除: 1 dockerrun-it-- rm --namemynginxnginx bash 后台启动一个mynginx的容器 1 dockerrun-d--namemynginxnginx 查看容器的具体信息: 1 dockerinspectDocker-Name 进入一个正在运行的容器,可以使用如下脚本(退出时需要注意,直接退出会终止容器): 1 2 3 #!/bin/bash pid=`dockerinspect-- format "``.`State`.`Pid`" $1` nsenter-t$pid-m-u-i-n-p #nsenter的参数不能少 如果没有这个命令可以采用yum install util-linux -y进行安装。 停止一个容器: 1 dockerstopmynginx 或者使用kill ID 的方式: 1 docker kill Docker-ID 杀死所有运行的容器: 1 docker kill $(docker ps -a-q) 查看所有容器(包含未运行的容器): 1 docker ps -a 删除所有的容器(强制删除正在运行的容器加-f 参数): 1 docker rm `docker ps --all| awk '{print$1}' | grep - v "CONTAINER" ` 容器端口管理 在启动容器的时候,如果不指定对应的参数,在容器外部是无法通过网络来访问容器内的网 络应用和服务的。当容器中运行一些网络应用,要让外部访问这些应用时,可以通过P或 者p参数来指定容器端口映射。当使用P(大写)时,docker会随机映射一个端口到容器内 部开放的端口 随机端口映射: 1 dockerrun-- rm -it-Pnginx 1 dockerrun-- rm -it-p127.0.0.1::80nginx 指定端口: 1 dockerrun-it-- rm -p80:80nginx #第一个端口为宿主机端口,第二个为容器内部端口 绑定多个端口: 1 dockerrun-- rm -it-p82:80-p822:22nginx 指定IP绑定端口: 1 dockerrun– rm itp127.0.0.1:80:80nginx 默认使用的是TCP协议,也可指定协议: 1 dockerrun– rm itp127.0.0.1:80:80 /udp nginx 网络功能 docker创建的容器默认是使用的Bridge进行网络通信的,默认情况下创建的容器都在172.17.0.0/16的bridge网络中。 docker会在宿主机创建一个docker0的网卡,默认情况下自带三种网络: 1 2 3 4 5 6 #dockernetworkls NETWORKIDNAMEDRIVERSCOPE 19d6580ec589bridgebridge local 7d48677c86bchosthost local 01b58b1cb415nonenull local host网络是在主机的网络堆栈上添加一个容器,使用host网络,主机和容器之间没有隔离。 例如,如果您使用主机网络运行在端口80上运行Web服务器的容器,则Web服务器可在主机端口80上使用。 host网络和none网络是无法直接配置的,我们可以配置和自定义bridge网络。 查看网络类型的具体说明: docker network inspect bridge 内容会显示当前分配的容器网络地址。 当我们要创建一个基于某个网络的容器时,使用 docker run --net=<NETWORK> 指定 容器互联 您可以使用Docker链接功能来允许容器相互发现,并将有关一个容器的信息安全地传输到另一个容器。 通过引入Docker网络功能,您仍然可以创建链接,但它们在默认网桥和用户定义网络之间的行为方式不同,容器的互联需要通过容器的name来指定。 创建一个名为web的容器,将它与test容器互联: 1 dockerrun-d--link test --namewebnginx 这样两个容器在默认的docker0中网络就打通了,其实也是利用DNS的主机和IP解析,在test容器中的/etc/hosts文件添加了web容器主机名解析配置。不过官方不推荐这样做,更好的做法是自定义一个bridge网络。 由于默认容器是以bridge方式接入宿主机网络的,所以这种方式如果不添加路由只支持在同一台宿主机上的容器互联。 自定义网络 建议使用用户定义的bridge网络来控制哪些容器可以相互通信,还可以使用自动DNS解析容器名称到IP地址。 Docker提供了创建这些网络的默认网络驱动程序。 您可以创建一个新的桥接网络,覆盖网络或MACVLAN网络。 您还可以创建一个网络插件或远程网络进行完整的自定义和控制。 您可以根据需要创建任意数量的网络,并且可以在任何给定时间将容器连接到这些网络中的零个或多个网络。 此外,您可以连接并断开网络中的运行容器,而无需重新启动容器。 当容器连接到多个网络时,其外部连接通过第一个非内部网络以字母顺序提供网络连接。 Bridge 网络 Bridge网络是Docker中最常见的网络类型。 Bridge网络类似于桥接网络,但是与传统的桥接网络不通,docker的bridge网络添加了一些新功能并删除一些旧的功能。 以下示例创建一些桥接网络,并对这些网络上的容器执行一些实验。 系统默认的是172.17.0.1/16网段的,如果我们想要修改这个网段(即docker0地址)需要修改启动文件: 1 vim /usr/lib/systemd/system/docker .service 在ExecStart=区域,加上参数: 1 --bip=10.10.0.1 /24 \ 这里指定的网段必须以1结尾,不能使用0表示一个网段,否则服务无法启动。 查看默认的docker0网络: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #ipa 1:lo:<LOOPBACK,UP,LOWER_UP>mtu65536qdiscnoqueuestateUNKNOWN link /loopback 00:00:00:00:00:00brd00:00:00:00:00:00 inet127.0.0.1 /8 scopehostlo valid_lftforeverpreferred_lftforever 2:ens3:<BROADCAST,MULTICAST,UP,LOWER_UP>mtu1500qdiscpfifo_faststateUPqlen1000 link /ether 52:54:00:7f:52:5abrdff:ff:ff:ff:ff:ff inet192.168.20.231 /24 brd192.168.20.255scopeglobalens3 valid_lftforeverpreferred_lftforever 3:docker0:<NO-CARRIER,BROADCAST,MULTICAST,UP>mtu1500qdiscnoqueuestateDOWN link /ether 02:42:3d:be:20:1dbrdff:ff:ff:ff:ff:ff inet10.10.0.1 /24 scopeglobaldocker0 valid_lftforeverpreferred_lftforever 76:br-0d7cff84eda0:<NO-CARRIER,BROADCAST,MULTICAST,UP>mtu1500qdiscnoqueuestateDOWN link /ether 02:42:98:d5:cf:bfbrdff:ff:ff:ff:ff:ff inet172.18.0.1 /16 scopeglobalbr-0d7cff84eda0 valid_lftforeverpreferred_lftforever 创建一个自定义的bridge网络: 1 dockernetworkcreatebackend #默认会使用bridge驱动 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #dockernetworkinspectbackend [ { "Name" : "backend" , "Id" : "0d7cff84eda06d5648a9ec3b079b4f41dfad836a7ea15dbdd2e1521318d93478" , "Scope" : "local" , "Driver" : "bridge" , "EnableIPv6" : false , "IPAM" :{ "Driver" : "default" , "Options" :{}, "Config" :[ { "Subnet" : "172.18.0.0/16" , "Gateway" : "172.18.0.1/16" } ] }, "Internal" : false , "Containers" :{}, "Options" :{}, "Labels" :{} } ] 1 2 3 4 5 6 #dockernetworkls NETWORKIDNAMEDRIVERSCOPE 0d7cff84eda0backendbridge local 239f46f2ac1cbridgebridge local 7d48677c86bchosthost local 01b58b1cb415nonenull local 创建一个容器,并指定backend网络: 1 2 3 #dockerrun--network=backend-itd--name=ts-netcentos 04ddbd92fea9c63f6ec54c7e63409054fabe1ae8a5d4ab4e4134722df9ca890c 查看自定义的网络状态: 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 #dockernetworkinspectbackend [ { "Name" : "backend" , "Id" : "0d7cff84eda06d5648a9ec3b079b4f41dfad836a7ea15dbdd2e1521318d93478" , "Scope" : "local" , "Driver" : "bridge" , "EnableIPv6" : false , "IPAM" :{ "Driver" : "default" , "Options" :{}, "Config" :[ { "Subnet" : "172.18.0.0/16" , "Gateway" : "172.18.0.1/16" } ] }, "Internal" : false , "Containers" :{ "04ddbd92fea9c63f6ec54c7e63409054fabe1ae8a5d4ab4e4134722df9ca890c" :{ "Name" : "ts-net" , "EndpointID" : "0b9d8cdf461a4a623693b86cb465c624573ff466453e6a0d202bd40937bf23c4" , "MacAddress" : "02:42:ac:12:00:02" , "IPv4Address" : "172.18.0.2/16" , "IPv6Address" : "" } }, "Options" :{}, "Labels" :{} } ] 启动到此网络的容器必须驻留在相同的Docker宿主机上。 网络中的每个容器都可以立即与网络中的其他容器进行通信。 虽然网络本身将容器与外部网络隔离开来。 用户自定义的bridge网络不支持link方式。可以使用之前介绍的端口映射或者使用expose的方式。 如果两个不同网络的容器要相互通信那应该怎么办呢? 其实很简单,容器也可以配置多个网络,就像物理机的多网卡一样,添加容器到其它网络可以给它再增加一个虚拟机网卡即可: dockernetworkconnectbackendtest1 给容器test1添加网络backend,无论容器是否开启此命令都能生效。这样容器test1中就会有两个网段的IP地址。 本文转自 酥心糖 51CTO博客,原文链接:http://blog.51cto.com/tryingstuff/1945403

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

GO map 基础操作

1 Gomap操作: 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 packagemain import "fmt" funcmain(){ varcountryMapmap[string]string /*创建集合*/ countryMap=make(map[string]string) /*map插入key-value对,各个国家对应的首都*/ countryMap[ "ShengRI" ]= "1988-04-09" /*使用key输出map值*/ for country:=rangecountryMap{ fmt.Println( "Capitalof" ,country, "is" ,countryMap[country]) } /*查看元素在集合中是否存在*/ captial,ok:=countryMap[ "ShengRI" ] /*如果ok是true,则存在,否则不存在*/ if (ok){ fmt.Println( "CapitalofUnitedStatesis" ,captial) } else { fmt.Println( "isnotok" ) } MyMap() } funcMyMap(){ varmyMapmap[string]string myMap=make(map[string]string) myMap[ "idc_id" ]= "2" myMap[ "idc_name" ]= "BeiJingIDC" myMap[ "idc_prod" ]= "OpenStack" myMap[ "idc_zone" ]= "BJ" myMap[ "idc_abs" ]= "2018-10-02" for m:=rangemyMap{ fmt.Println(m,myMap[m]) } delete (myMap, "idc_abs" ) fmt.Println(myMap) myMap[ "idc_abs" ]= "2088-10-02" fmt.Println(myMap) _,ok:=myMap[ "idc_zone" ] if ok{ fmt.Println(myMap[ "idc_zone" ], "isok" ) } } 本文转自 swq499809608 51CTO博客,原文链接:http://blog.51cto.com/swq499809608/1920920

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

六、WEB服务基础

Web、服务器和相关的Web应用程序都是通过HTTP相互通信的。HTTP(HyperText Transfer Protocol,超文本传输协议)是现代全球因特网中使用的公共语言。Web内容都是存储在Web服务器上的,Web服务器所使用的是HTTP协议,因此经常会被称为HTTP服务器。这些HTTP服务器存储了因特网中的数据,如果HTTP客户端发出请求,它们会提供数据。客户端向服务器发送HTTP请求,服务器会在HTTP响应中回送所请求的数据。 资源与资源的类型 Web服务器就是Web资源的宿主,Web资源就是Web内容的源头。最简单的Web资源就是Web服务器文件系统中的静态文件。这些文件可以包含任意内容:文本文件、HTML文件、word文件、AVI电影文件等。但是资源并不一定是静态文件,资源还可以是根据需要生成内容的软件程序,这些程序可以根据用户身份、所请求的信息来产生不同的内容。 因特网上有数千种不同类型的数据类型,HTTP给每种要通过Web传输的对象都打上了MIME类型的数据格式标签。Web服务器会为所有的HTTP对象数据附加MIME(Multipurpose Internet Mail Extension,多用途因特网邮件扩展)类型。当Web浏览器从服务器中取回一个对象时,会查看相关的MIME类型,看看能否知道该如何处理该对象,大多数浏览器都可以处理数百种常见的对象类型。 MIME类型是一种文本标记,表示一种主要的对象类型和一个特定的子类型,中间用斜杠分隔。 HTML格式的文本文档由text/html类型来标记 普通ASCII文本文档由text/plain类型来标记 JPEG版本图片为image/jpeg类型 GIF版本图片为image/gif类型 ... URI与URL 每个Web服务器资源都有一个名字,这样客户端可以通过该名字找到所需要的资源。服务器资源名被称为统一资源标识符(Uniform Resource Indentifier,URI)。URI就像英特网上的邮政地址一样,在世界范围内唯一标示并定位信息资源。 例如:http://www.joes-hardware.com/specials/saw-blade.gif 统一资源定位符(Uniform Resource Locator,URL)是资源标识符最常见的形式,URL描述了一台特定服务器上某资源的特定位置。它们可以明确说明如何从哟个精确、固定的位置获取资源。如图显示了URL如何精确的说明某自愿的位置以及如何访问。 事务 下图展示了客户端如何通过HTTP与Web服务器及其资源进行事务处理。一个HTTP事务由一条(客户端发往服务器端)请求和一个响应(服务器端发回客户端)组成。这种通信通过HTTP报文的格式画数据块进行。 HTTP支持几种不同的请求命令,这些命令被称为HTTP方法(HTTP mothod)。每种HTTP请求报文都包含一个方法。这些方法告诉服务器要执行什么动作,常见的HTTP方法有: GET 请求获取一个资源,需要服务器发送 HEAD 跟GET相似,但其不需要服务发送资源而仅传回响应首部 PUT 与GET相反,向服务端写入文档;例如发布系统 DELETE 请求删除URL指向的资源 OPTIONS 探测服务器端对某资源所支持的请求方法 TRACE 跟踪请求要经过的防火墙、代理或网关等 POS 支持HTML表单提交,表单中有用户填入的数据,这些数据会发送到服务器端,由服务器存储至某位置(例如发送处理程序) 每条HTTP响应报文返回时都会携带一个状态码。状态码是一个三位数字的代码,告知客户端请求是否成功,或者是否需要采取其他动作,常见的状态码有: 1xx 纯信息性状态码 2xx “成功”类的信息(200, 201, 202) 3xx 重定向状态码 301:Moved Permanently,在响应报文中用首部“Location: URL”指定资源现在所处位置 302:Found,在响应报文中使用首部“Location: URL”指定临时资源位置; 304:Not Modified,条件式请求中使用;(缓存中使用) 4xx 客户端错误类的信息 403:Forbidden,请求被服务器拒绝 404:Not Found,服务器无法找到请求的URL 405:Method Not Allowed,不允许使用此方法请求相应的URL 5xx 服务器端错误类的信息 500:Internal Server Error,服务器内部错误; 502:Bad Gateway,代理服务器从上游收到了一条伪响应; 503:Service Unavailable,服务器此时无法提供服务,但将来可能可用; 504:Gateway Timeout,网关代理请求后端服务时,后端服务没有及时响应。 报文 HTTP报文是由一行一行的简单字符串组成.HTTP报文都是纯文本,而不是二进制代码,所以可以方便地对其进行读写。下图展示了一个简单事务所使用的HTTP报文。 HTTTP报文主要分为三个部分:起始行、首部字段、主体。 请求报文语法: <method> <request-URL> <version> <headers>(name:value) (必须空一行) <entity-body> 报文主体 响应报文语法: <version> <status> <reason-phrase> <headers> (必须空一行) <entity-body> <method>:请求方法,希望服务器端执行的动作,如GET、HEAD、POST等 <request-url>:请求的资源,可以是相对路径,也是完整的URL <version>:协议版本,格式HTTP/<major>.<minor>,如http/1.0 <headers>:HTTP首部 <status>:状态码 <reason-phrase>:原因短语,数字状态码易读信息 <entity-body>:主体部分 HTTTP协议版本 http/0.9:仅纯文本(超链接), ASCII http/1.0:支持多媒体数据的处理。支持保持连接。 http/1.1:支持持久连接。更精细的缓存控制 HTTP-NG(又称HTTP/2.0),重点是性能的大幅优化,以及更强大的服务逻辑远程执行框架,但没有要取代http/1.1的计划。 HTTP首部 HTTP首部和方法配合工作,共同决定了客户端和服务器能做什么。首部通常可以分为五种类型: 通用首部:请求报文和响应报文都可以使用的 HTTP/1.0引入允许HTTP应用程序缓存对象本地副本的首部,这样就不需要总是直接从服务器段获取。 请求首部:只在请求报文中有意义 请求的信息性首部: Accept首部: 条件请求首部: 安全请求首部: 代理请求首部: 响应首部:只在请求报文中有意义 响应的信息性首部 协商首部 安全响应首部 实体首部:用于指定实体属性 实体的信息性首部 内容首部 实体缓存首部 扩展首部:非标准首部,可能是由程序开发者创建的,例如X-Forward-For HTTTP的实现软件 客户端: GUI:IE、Firefox、Safari、chrome、Opera CLI:elinks, curl 服务端: Server: httpd(ASF基金会)、nginx、lighttpd App Server: IIS、tomcat、jetty、resin 6.2、Web服务器处理连接请求的架构方式 1、单线程web服务器(Single-threaded web servers) 此种架构方式中,web服务器一次处理一个请求,结束后读取并处理下一个请求。在某请求处理过程中,其它所有的请求将被忽略,因此,在并发请求较多的场景中将会出现严重的必能问题。 2、多进程/多线程web服务器 此种架构方式中,web服务器生成多个进程或线程并行处理多个用户请求,进程或线程可以按需或事先生成。有的web服务器应用程序为每个用户请求生成一个单独的进程或线程来进行响应,不过,一旦并发请求数量达到成千上万时,多个同时运行的进程或线程将会消耗大量的系统资源。 3、I/O多路复用web服务器 为了能够支持更多的并发用户请求,越来越多的web服务器正在采用多种复用的架构——同步监控所有的连接请求的活动状态,当一个连接的状态发生改变时(如数据准备完毕或发生某错误),将为其执行一系列特定操作;在操作完成后,此连接将重新变回暂时的稳定态并返回至打开的连接列表中,直到下一次的状态改变。由于其多路复用的特性,进程或线程不会被空闲的连接所占用,因而可以提供高效的工作模式。 4、多路复用多线程web服务器 将多进程和多路复用的功能结合起来形成的web服务器架构,其避免了让一个进程服务于过多的用户请求,并能充分利用多CPU主机所提供的计算能力。 一次web请求响应的过程 1、建立连接——接受或拒绝客户端连接请求; 2、接收请求——通过网络读取HTTP请求报文; 3、处理请求——解析请求报文并做出相应的动作; 4、访问资源——访问请求报文中相关的资源; 5、构建响应——使用正确的首部生成HTTP响应报文; 6、发送响应——向客户端发送生成的响应报文; 7、记录日志——当已经完成的HTTP事务记录进日志文件; 本文转自 梦想成大牛 51CTO博客,原文链接:http://blog.51cto.com/yinsuifeng/1930580,如需转载请自行联系原作者

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

Docker 基础 : 网络配置

大量的互联网应用服务包含多个服务组件,这往往需要多个容器之间通过网络通信进行相互配合。Docker 目前提供了映射容器端口到宿主主机和容器互联机制来为容器提供网络服务。接下来我们将讲述 Docker 的网络功能,包括使用端口映射机制来将容器内应用服务提供给外部网络,以及通过容器互联系统让多个容器之间进行快捷的网络通信。 端口映射实现访问容器 从外部访问容器应用 在启动容器的时候,如果不指定对应的参数,在容器外部是无法通过网络来访问容器内的网络应用和服务的。当容器中运行了一些网络应用,要让外部访问这些应用时,可以通过 -P 或 -p 参数来指定端口映射。当使用 -P 参数时,Docker 会随机选择一个主机可用的端口映射至容器内部开放的网络端口: $ docker run -d -P training/webapp python app.py 使用 docker ps 命令查看一下映射结果: 我这里主机的 32768 端口映射到了容器的 5000 端口。此时访问主机的 32768 端口就可以访问容器内 web 应用提供的内容。-p (小写)参数则可以指定要映射的主机端口。注意,在一个指定的主机端口上只能绑定一个容器。我们可以通过不同的参数格式映射主机和容器之间的端口:Ip:hostPort:containerPortIp::containerPorthostPort:containerPort 映射所有接口地址 使用 hostPort:containerPort 格式将本地的 5000 端口映射到容器的 5000 端口,可以执行如下命令: $ sudo docker run -d -p 5000:5000 training/webapp python app.py 此时默认会绑定本地所有接口上的所有地址(如果主机有多个 IP,那么每个 IP 的 5000 端口都映射到了容器的 5000 端口)。 多次使用 -p 参数可以绑定多个端口: $ sudo docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py 映射到指定地址的指定端口 可以使用 ip:hostPort:containerPort 格式的参数指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1: $ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py 映射到指定地址的任意端口 使用 ip::containerPort 格式的参数可以绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口: $ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py 另外还可以使用 udp 标记来指定 udp 端口: $ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py 查看映射端口配置 使用 docker port 命令可以查看当前映射的端口配置,也可以查看到绑定的地址: 上图中 mad_einstein 是容器的名字,32768 是容器的 5000 端口映射到主机上的端口。 容器互联实现容器间通信 容器的连接(linking)系统是除了端口映射外另一种可以与容器中应用进行交互的方式。它会在源和接收容器之间创建一个隧道,接收容器可以看到源容器指定的信息。 自定义容器命名 连接系统依据容器的名称来执行。因此,首先需要自定义一个好记的容器名称。虽然当创建容器的时候,系统默认会分配一个名字,但自定义命名容器有两个好处:1. 自定义的名称比较好记。2. 当要连接其他容器的时候,可以作为一个有用的参考点,比如连接 web 容器到 db 容器。 使用 –name 标记可以为容器自定义名称: $ sudo docker run -d -P –name web training/webapp python app.py 使用 docker ps 来验证设定的名称: 也可以使用 docker inspect 来查看容器的名称: 注意,容器的名称是唯一的。如果已经命名了一个叫 web 的容器,当你要再次使用 web 这个名称的时候,需要先用 docker rm 来删除之前创建的同名容器。在执行 docker run 的时候如果添加 – rm 标记,则容器在终止后会立刻删除。但 – rm 和 -d 不能同时使用。 容器互联 使用 –link 参数可以让容器之间安全的进行交互。下面先创建一个新的数据库容器: $ sudo docker run -d –name db training/postgres 删除之前创建的web容器: $ sudo docker rm -f web 然后创建一个新的 web 容器,并将它连接到 db 容器: $ sudo docker run -d -P –name web –link db:db training/webapp python app.py 此时,db 容器和 web 容器建立互联关系。--link 参数的格式为 –link name:alias,其中 name 是要连接的容器的名称,alias 是这个连接的别名。 Docker 在两个互联的容器之间创建了一个安全隧道,而且不用映射它们的端口到宿主主机上。在启动 db 容器的时候没有使用 -p 和 -P 标记,从而避免了暴露数据库端口到外部网络上。Docker 通过两种方式为容器公开连接信息:1. 环境变量。2. 更新 /etc/hosts文件。 使用 env 命令来查看 web 容器的环境变量: $ sudo docker run –rm –name web2 –link db:db training/webapp python app.py env 其中 DB_ 开头的环境变量是供 web 容器连接 db 容器使用的。除了环境变量,Docker 还添加了 host 信息到容器的 /etc/hosts 文件中。下面查看web容器的 hosts 文件: $ sudo docker run -t -I –rm –link db:db training/webapp /bin/bash 上图中有两个 host 信息,第一个是 db 容器的名称 ip 和主机名。第二个是 web 容器,web 容器用自己的 id 作为默认主机名。我们可以通过 ping 命令测试 web 容器到db容器的连接: 如图所示,名称 db 被解析成了 172.17.0.24。 本文转自sparkdev博客园博客,原文链接:http://www.cnblogs.com/sparkdev/p/6286081.html,如需转载请自行联系原作者

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

MySQL必会基础命令

1.1 登陆数据库。 mysql-uroot-poldboy123-S/data/3306/mysql.sock 1.2 查看数据库版本及当前登录用户是什么。 selectversion(); selectuser(); 1.3 创建GBK字符集的数据库oldboy,并查看已建库的完整语句。 createdatabaseoldboycharactersetgbkcollategbk_chinese_ci; showcreatedatabaseoldboy\G 1.4 创建用户oldboy,使之可以管理数据库oldboy。 grantallonoldboy.*to'oldboy'@'localhost'identifiedby'oldboy123'; 1.5 查看创建的用户oldboy拥有哪些权限。 showgrantsforoldboy@localhost\G 1.6 查看当前数据库里有哪些用户。 selectuser,hostfrommysql.user; 1.7 创建管理员帐户admin grantallon*.*to'admin'@'localhost'identifiedby'admin123'withgrantoption; 1.8 进入oldboy数据库 useoldboy; 1.9 创建test表:innodb引擎,字符集为GBK,字段为id int(4)和name varchar(16),查看建表结构及SQL语句。 createtabletest( idint(4), namevarchar(16) )ENGINE=innodbDEFAULTCHARSET=gbk; desctest;#<==等价于命令:showcolumnsfromtest; showcreatetabletest\G 1.10 插入一条数据 1,oldboy insertintotestvalues('1','oldboy'); 1.11 批量插入数据 2,老男孩,3,etiantian。要求中文不能乱码。 insertintotestvalues('2','老男孩'),('3','etiantian'); 1.12 查询插入的所有记录,查询名字为oldboy的记录。查询id大于1的记录。 select*fromtestwherename='oldboy'; select*fromtestwhereid>1; 1.13 把数据id等于1的名字oldboy更改为oldgirl。 updatetestsetname='oldgirl'whereid=1; 1.14 在字段name前插入age字段,类型tinyint(2)。 alter table test add name tinyint(2) after id; 1.15 备份oldboy库及mysql库。 mysqldump -uroot -poldboy123 -S /data/3306/mysql.sock --events -B oldboy mysql >/opt/bak_$(date +%F).sql egrep -v "#|^$|--|\/" /opt/bak_2017-06-06-13时36分37秒.sql 1.16 删除表中的所有数据,并查看。 truncatetabletest;#<==物理删除,一次性清空,不可以rollback deletefromtest;#<==逻辑删除,一行一行的删,比较慢,可以rollback 1.17 删除表test和oldboy数据库并查看 droptabletest; dropdatabaseoldboy; 1.18 Linux命令行恢复以上删除的数据。 mysql-uroot-poldboy123-S/data/3306/mysql.sock</opt/bak_2017-06-07-22时13分20秒.sql 1.19 把GBK字符集修改为UTF8(可选,注意,此题有陷阱)。 1.先导出表中数据 mysqldump-uroot-poldboy123-S/data/3306/mysql.sock-Boldboy>/opt/test.sql egrep-v"^$|--|\/"/opt/test.sql#<==可以看到这一行:ENGINE=MyISAMDEFAULTCHARSET=gbk; 2.修改字符集 sed-i's#CHARSET=gbk#CHARSET=utf8#g'/opt/test.sql egrep-v"^$|--|\/"/opt/test.sql#<==验证:)ENGINE=MyISAMDEFAULTCHARSET=utf8; 3.恢复数据 在sql文件中添加一条setnamesutf8;并恢复 mysql-uroot-poldboy123-S/data/3306/mysql.sockoldboy</opt/test.sql 1.20 MySQL密码丢了,如何找回实战? [root@db01~]#netstat-tunlp|grep3306#<==先查看服务是否正常 tcp000.0.0.0:33060.0.0.0:*LISTEN62358/mysqld [root@db01~]#kill62358#<==kill掉进程的pid [root@db01~]#netstat-tunlp|grep3306#<==mysql进程已关闭 [root@db01~]#mysqld_safe--help#<==利用mysqld_safe命令指定配置文件,跳过授权表来破密码 [root@db01~]#mysqld_safe--defaults-file=/data/3306/my.cnf--skip-grant-tables2>&1>/dev/null& [root@db01~]#mysql-S/data/3306/mysql.sock#<==无密码登录进多实例3306 mysql>selectuser,host,passwordfrommysql.userwhereuser='root'andhost='localhost'; +------+-----------+-------------------------------------------+ |user|host|password| +------+-----------+-------------------------------------------+ |root|localhost|*FE28814B4A8B3309DAC6ED7D3237ADED6DA1E515| +------+-----------+-------------------------------------------+ 1rowinset(0.00sec)#<==先看下mysql库,user表里的字段内容 mysql>updatemysql.usersetpassword=PASSWORD("oldboy123")whereuser='root'andhost='localhost';#<==利用update命令来更新root@localhost用户的密码 mysql>flushprivileges;#<==记得刷新授权表,否则不会立马生效的 QueryOK,0rowsaffected(0.00sec) [root@db01~]#sed-i's#mysql_pwd="oldboy456"#mysql_pwd="oldboy123"#g'/data/3306/mysql [root@db01~]#grepmysql_pwd=/data/3306/mysql#<==修改启动脚本的密码,才能利用命令来停止服务 mysql_pwd="oldboy123" [root@db01~]#/data/3306/mysqlstop#<==先停掉服务,因为有跳过授权表的参数在 StopingMySQL... [1]+Donemysqld_safe--defaults-file=/data/3306/my.cnf--skip-grant-tables2>&1>/dev/null [root@db01~]#/data/3306/mysqlstart#<==启动 StartingMySQL... [root@db01~]#ss-tunlp|grep3306#<==侦听正常 tcpLISTEN0600*:3306*:*users:(("mysqld",66695,12)) [root@db01~]#mysql-uroot-poldboy123-S/data/3306/mysql.sock#<==成功登录 1.21 MySQL内中文数据乱码的原理及如何防止乱码?(可选)。 保证以下的字符集一致即可 mysql>showVARIABLESlike'character_set%'; +--------------------------+--------------+ |Variable_name|Value| +--------------------------+--------------+ |character_set_client|utf8|#<==客户端字符集 |character_set_connection|utf8|#<==客户端连接字符集,配置文件指定或建库表指定 |character_set_database|utf8|#<==数据库的字符集 |character_set_filesystem|binary|#<==文件系统字符集 |character_set_results|utf8|#<==客户端返回结果字符集 |character_set_server|utf8|#<==服务器字符集,配置文件指定或建库表指定 |character_set_system|utf8|#<==Linux系统的字符集 |character_sets_dir|/application/mysql-5.5.49/share/charsets/| +--------------------------+-------------------------------------------+ 8rowsinset(0.01sec) 1.22 在把id列设置为主键,在name字段上创建普通索引。 altertabletestaddprimarykey(id); altertabletestaddindexindex_name(name); 1.23 在字段name后插入手机号字段(shouji),类型char(11)。 altertabletestaddshoujichar(11); 1.24 所有字段上插入2条记录(自行设定数据) insertintotestval-ues('4','18','chen','15298914487'),('5','19','he','15298913929'); 1.25 在手机字段上对前8个字符创建普通索引。 altertabletestaddindexindex_shouji(shouji(8)); 1.26 查看创建的索引及索引类型等信息。 desctest; showcreatetabletest\G showindexfromtest\G 1.27 删除name,shouji列的索引。 altertabletestdropindexindex_name; altertabletestdropindexindex_shouji; 1.28 对name列的前6个字符以及手机列的前8个字符组建联合索引。 altertabletestdropindexindex_shouji; 1.29 查询手机号以152开头的,名字为chen的记录(此记录要提前插入)。 select * from test where name='chen' and shouji like '152%'; 1.30 查询上述语句的执行计划(是否使用联合索引等)。 explain select * from test where name='chen' and shouji like '152%'\G 1.31 把test表的引擎改成MyISAM。 alter table test ENGINE=MYISAM;

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

Android基础知识

Android特性: Application frameworkenabling reuse and replacement of components Dalvik virtual machineoptimized for mobile devices Integrated browserbased on the open sourceWebKitengine Optimized graphicspowered by a custom 2D graphics library; 3D graphics based on the OpenGL ES 1.0 specification (hardware acceleration optional) SQLitefor structured data storage Media supportfor common audio, video, and still image formats (MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF) GSM Telephony(hardware dependent) Bluetooth, EDGE, 3G, and WiFi(hardware dependent) Camera, GPS, compass, and accelerometer(hardware dependent) Rich development environmentincluding a device emulator, tools for debugging, memory and performance profiling, and a plugin for the Eclipse IDE 框架: 应用程序部件: Activity Services Content Providers Broadcast receiver Manifest 文件 整个程序的功能清单,包括包的定义、版本声明,应用程序Activity、ICON、service、intent filter等的声明。 在Eclipse中可以通过Manifest Editor方便编辑(右键打开)。 <?xml version="1.0" encoding="utf-8"?> <manifest . . . > <application . . . > <activity android:name="com.example.project.FreneticActivity" android:icon="@drawable/small_pic.png" android:label="@string/freneticLabel" . . . > </activity> . . . </application> </manifest> Activities and Tasks 一个task就是用户感觉上的"应用程序",task 是一组相互关联的activity集合组成的栈(这些activity可能属于多个应用程序). 栈底就是应用程序启动时显示的第一个activity。栈顶activity就是用户在屏幕上看到的activity。当一个activity启动一个新的activity时,新的activity就会被压入栈中。当用户点击"back " 按钮时,位于栈顶的activity将会被弹出栈。我们举个例子,假设task中有两个activity,分别是 A 和 B,其中A是位于栈顶的activity,用户点击"back"后, A就被弹出栈, B 就成为了新的栈顶activity,然后 activity B 会显示在屏幕上。 通常来讲,task栈中的activity不会被改变排列顺序,只有出栈和入栈操作。 A task is a stack of activities, not a class or an element in the manifest file. So there's no way to set values for a task independently of its activities. Values for the task as a whole are set in the root activity. For example, the next section will talk about the "affinity of a task"; that value is read from the affinity set for the task's root activity. 一个task中的所有activity是作为一个整体来移动的--移到前台后者后台。就个例子,假设当前 task 栈中有ABCD4个activity,A是栈顶activity,也就是在屏幕上显示的activity,用户点击了"home"键,启动了一个新的应用程序,则 ABCD 4个activity都会被移动到后台。过了一会,用户又点击了"home"键,并重新选择了先前的程序,则 ABCD 都被移动到前台,A 仍然作为栈顶activity 被显示在屏幕上,然后用户点击了"back",A被弹出栈,B作为新的栈顶activity被显示在屏幕上。 前面所讲的都是task的默认行为,我们可以通过某些方法改变task 的默认行为。 不同的task里的activity是由affinity来区别的.默认情况下每个task里面的activities都有相同的affinity。但是可以通过<activity> 标签里taskAffinity属性来修改某个activity的affinity,此时需要设置FLAG_ACTIVITY_NEW_TASK标志,并且allowTaskReparenting 属性设置为true。关于这点的文档解释是:As described earlier, a new activity is, by default, launched into the task of the activity that calledstartActivity(). It's pushed onto the same stack as the caller. However, if the Intent object passed tostartActivity()contains theFLAG_ACTIVITY_NEW_TASKflag, the system looks for a different task to house the new activity. Often, as the name of the flag implies, it's a new task. However, it doesn't have to be. If there's already an existing task with the same affinity as the new activity, the activity is launched into that task. If not, it begins a new task. 注意:在使用FLAG_ACTIVITY_NEW_TASK属性(singleTask和singleInstance类似)时,无法回退到调用者。 activity在task中加载方式主要有四种: 1.standard(the default mode):一个intent发过来之后,都会产生一个新的activity来响应这个intent; 2.singleTop:保持stack顶端的那个activity.也就是说,如果一个intent是由stack顶端的activity处理的话,将不会新建一个新的activity来处理,而是由原来的那个activity处理; 3.singleTask:对于这个activity则会新建一个task.也就是说,对于这个activity,会分配一个新的affinity; 4.singleInstance:identical to "singleTask",并保证这个activity唯一. 既然对初始加载的过程有所规定,那么也就很自然地会有结束过程的一些方式: acitivity在退出的时候,必然会影响到task的stack,因此,android对acitivity的行为方式也做了规定. 1.alwaysRetainTaskState属性.保证stack不变.默认状态下,一个task长期不活动的话,会退化到root activity,也就是弹出stack,只保留底部的一个acitivity. 2.clearTaskOnLaunch属性.这个会在acitivity加载的时候清空task的stack. 3.finishOnTaskLaunch属性.某种程度上说这个属性保证了某项task是唯一的.因为当一个同类的task加载的时候,如果此属性为true,那么就会先退出之前的task,然后再加载这个task. 如果FLAG_ACTIVITY_CLEAR_TOP属性为真,则结束activity时,所有处于该activity堆栈之上的activity都会同时清除,FLAG_ACTIVITY_CLEAR_TOP is most often used in conjunction with FLAG_ACTIVITY_NEW_TASK. When used together, these flags are a way of locating an existing activity in another task and putting it in a position where it can respond to the intent. 本文转自feisky博客园博客,原文链接:http://www.cnblogs.com/feisky/archive/2009/12/30/1636377.html,如需转载请自行联系原作者

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

Android makefile编写基础

首先来看一个简单的Android makefile,这个是我上篇文章写的,重新摘出来: LOCAL_PATH:=$(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := eng LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog LOCAL_SRC_FILES:= \ ppp.c LOCAL_MODULE:= PPPreboot include $(BUILD_EXECUTABLE) #include $(BUILD_SHARED_LIBRARY)下面对上面的语法进行解析: LOCAL_PATH:=$(call my-dir) 定义了当前模块的相对路径 include $(CLEAR_VARS) 清空了当前的环境变量 LOCAL_MODULE_TAGS := eng 指定模块在eng模式下才进行编译 LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog 编译需要的库 LOCAL_SRC_FILES:ppp.c 编译所需要的目标源文件,一般都是当前目录下,或者依赖于其它目录下 LOCAL_MODULE:= PPPreboot 编译生成该目标的名称,也就是最终的可执行文件 include $(BUILD_EXECUTABLE) 编译所生成的目标的文件格式 其中: my-dir在build/core/definitions.mk定义CLEAR_VARS在build/core/config.mk定义 以下就是我之前写的源码,简单的功能。 #include <stdio.h> #include <stdlib.h> #include <android/log.h> #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "keymatch", __VA_ARGS__) int main(void) { int i ; freopen("/dev/ttyMT0", "a", stdout);setbuf(stdout, NULL); freopen("/dev/ttyMT0", "a", stderr);setbuf(stderr, NULL); LOGD("YYX---->reboot system!!!!!!--->201612.1\n"); system("reboot"); return 0 ; } makefile还有源码写完以后我们就可以进行编译了。首先,需要source build/envsetup.sh 初始化参数和环境变量接着lunch 对应的平台的版本接着就拥有了mm、mmm等编译工具然后对刚刚写的程序进行手动编译: mmm external/test/ 编译成功信息如下: PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=6.0 TARGET_PRODUCT=em_t8350_emmc TARGET_BUILD_VARIANT=eng TARGET_BUILD_TYPE=release TARGET_BUILD_APPS= TARGET_ARCH=arm TARGET_ARCH_VARIANT=armv7-a-neon TARGET_CPU_VARIANT=cortex-a7 TARGET_2ND_ARCH= TARGET_2ND_ARCH_VARIANT= TARGET_2ND_CPU_VARIANT= HOST_ARCH=x86_64 HOST_OS=linux HOST_OS_EXTRA=Linux-3.13.0-32-generic-x86_64-with-Ubuntu-14.04-trusty HOST_BUILD_TYPE=release BUILD_ID=MRA58K OUT_DIR=out ============================================ PRODUCT_COPY_FILES frameworks/base/data/sounds/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg ignored. PRODUCT_COPY_FILES device/pskyed/em_t8350_emmc/init.recovery.mt8127.rc:root/init.recovery.mt8127.rc ignored. PRODUCT_COPY_FILES device/pskyed/em_t8350_emmc/handheld_core_hardware.xml:system/etc/permissions/handheld_core_hardware.xml ignored. make: Entering directory `/mnt/sdb1/yangyx/MT8127_t8350_Debug_Camera_20161121/MT8127_M0_MP8_0407_for_t8350' build/core/Makefile:614: warning: overriding commands for target `out/target/product/em_t8350_emmc/boot.img' build/core/Makefile:39: warning: ignoring old commands for target `out/target/product/em_t8350_emmc/boot.img' No private recovery resources for TARGET_DEVICE em_t8350_emmc Import includes file: out/target/product/em_t8350_emmc/obj/EXECUTABLES/PPPreboot_intermediates/import_includes target thumb C: PPPreboot <= external/test/ppp.c target Executable: PPPreboot (out/target/product/em_t8350_emmc/obj/EXECUTABLES/PPPreboot_intermediates/LINKED/PPPreboot) target Unpacked: PPPreboot (out/target/product/em_t8350_emmc/obj/EXECUTABLES/PPPreboot_intermediates/PACKED/PPPreboot) target Symbolic: PPPreboot (out/target/product/em_t8350_emmc/symbols/system/bin/PPPreboot) Export includes file: external/test/Android.mk -- out/target/product/em_t8350_emmc/obj/EXECUTABLES/PPPreboot_intermediates/export_includes target Strip: PPPreboot (out/target/product/em_t8350_emmc/obj/EXECUTABLES/PPPreboot_intermediates/PPPreboot) Install: out/target/product/em_t8350_emmc/system/bin/PPPreboot make: Leaving directory `/mnt/sdb1/yangyx/MT8127_t8350_Debug_Camera_20161121/MT8127_M0_MP8_0407_for_t8350' #### make completed successfully (2 seconds) #### 输出的文件就在out/target/product/em_t8350_emmc/system/bin/PPPreboot,用什么手段执行它都可以,就看你的需求了。

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

Sqoop基础学习(1)

1. Sqoop的导入过程 在开始导入之前,Sqoop会通过JDBC来获得所需要的数据库元数据 1.导入表的列名、数据类型等; 2.接着这些数据库的数据类型(varchar、number等)会把映射成Java的数据类型(String、int等),根据这些信息,Sqoop会生成一个与表名同名的类用来完成反序列的工作,保持表中的每一行记录; 3.Sqoop启动MapReduce作业 4.启动的作业在input的过程中,会通过JDBC读取数据库表中的内容; 5.这是会使用Sqoop生成的类进行反序列话 6.最后再将这些记录写到HDFS中,在写入HDFS的过程中,同样会使用Sqoop生成的类进行序列化。 2. Sqoop的导出过程 1/2 Sqoop根据目标表的结构会生成一个Java类 3.该类作用为序列化和反序列化 4.接着启动一个MapReduce作业 5.在作业中会生成的Java类从HDFS中读取数据 6.并生成一批INSERT语句,每条语句都会向MySQL的目标表中插入多条记录

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

openstack之网络基础

L1:物理层L2:数据链路层,基于mac地址的通信,通过交换机连接;对等传输,即交换机上的一个主机发一个包,连接在该交换机上的所有机器都能收到;L3:网络层,基于ip地址,路由器设备,连接不同网段,进行路由选择; 交换机/路由器的区别:1、工作层级不同,交换机在L2,路由器在L3;2、数据转发依据对象不同:交换机传输基于mac地址的数据帧,路由器传输基于ip地址的ip数据包;3、解决问题不同:交换机使得同网段互通/路由器使得多网段互通; IP Tableip netns exec router-ns iptables -t nat -nL 混杂模块:1、接收所有经过设备(网卡)的数据包2、一般用于网络抓包;3、Floating IP功能实现查看网卡是否打开混杂模式;root@222-132-16-52:~# ifconfig br0br0 Link encap:Ethernet HWaddr c8:0a:a9:57:70:b0 inet addr:222.132.16.52 Bcast:222.132.16.255 Mask:255.255.255.0 inet6 addr: fe80::ca0a:a9ff:fe57:70b0/64 Scope:Link #UP BROADCAST RUNNING MULTICAST# MTU:1500 Metric:1 RX packets:32138224 errors:0 dropped:0 overruns:0 frame:0 TX packets:21550681 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:3797977700 (3.7 GB) TX bytes:4267007875 (4.2 GB)

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

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文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册