首页 文章 精选 留言 我的

精选列表

搜索[高并发],共10000篇文章
优秀的个人博客,低调大师

Nacos发布 v0.2 版本,无缝支持 Spring Cloud 微服务生态及可用集群模式

近日,阿里巴巴新开源项目Nacos 发布了 v0.2 版本,该版本开始支持完整的Spring生态技术栈,这包括 Spring Framework、Spring Boot和Spring Cloud。 为了让更多的Spring用户可以在生产上基于 Nacos 做微服务平台的服务发现、配置管理、服务管控,Nacos v0.2版本向下兼容了大部分Spring生态的版本,这其中包括**SpringFramework 3.2.18+、Spring Boot 1.4.1+ 和 2.0.3+以及Spring Cloud E版、F版。** 相比Consul、Eureka和Spring CloudConfig的原生解决方案,Nacos 计划在更适应云环境、多配置管理、容灾、管控、容量支撑和易运维等方面做更多的能力扩展,而在这次与Spring生态融合的设计

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

都说 Python 赶超 Java,爬取拉勾网数据发现它的薪资已至 50K!

人工智能的快速发展以及大数据时代的来临,使得 Python 语言不仅在人工智能领域大放异彩,在数据处理上也有着得天独厚的优势,在 Web 开发、网络编程、自动化运维、游戏开发、金融等领域扮演着越来越重要的角色。 百度搜索指数表明,2017 年 7 月份开始,Python 的搜索指数已经超过了 Java。Python 语言的热门由此可见一斑。 本文中,笔者决定在拉勾网(一家为互联网从业者提供工作机会的招聘网站)上爬取相关 Python 职位信息,对职位数据(薪酬、学历要求、区域信息、工作经验等)进行图形可视化分析。 01 前期准备 1、网页分析 打开拉勾网网站搜索 Python,可以发现每页有 15 条职位信息数据,最多有 30 页数据可以查看,共 450 条职位信息。我们需要获取的信息包括:职位、公司名称、薪酬范围、所在区域、学历要求、工作经验、公司融资情况、公司人数、工作要求描述。 2、请求数据分析 通过 Chrome 浏览器访问拉勾网,打开 Console 控制台可以发现,当进行翻页的时候,是通过 xhr 的请求方式请求的。通过观察,我们可以发现,URL 里面的 city 代表的是城市,post 参数 kd 代表的是搜索的职位,pn 是 page number,表示页码。 3、职位列表JSON返回数据的分析获取 通过 JSON 库进行数据的解析,获取相关信息。需要注意的是,我们需要记得保留 positionID,用于下一步获取工作描述信息。 def get_lagou(page,city,kd): url = "https://www.lagou.com/jobs/positionAjax.json" querystring = {"px": "new", "city": city, "needAddtionalResult": "false", "isSchoolJob": "0"} payload = "first=false&pn=" + str(page) + "&kd="+str(kd) cookie = "JSESSIONID=" + get_uuid() + ";"\ "user_trace_token=" + get_uuid() + "; LGUID=" + get_uuid() + "; index_location_city=%E6%88%90%E9%83%BD; " \ "SEARCH_ID=" + get_uuid() + '; _gid=GA1.2.717841549.1514043316; ' \ '_ga=GA1.2.952298646.1514043316; ' \ 'LGSID=' + get_uuid() + "; " \ "LGRID=" + get_uuid() + "; " headers = {'cookie': cookie,'origin': "https://www.lagou.com",'x-anit-forge-code': "0",'accept-encoding': "gzip, deflate, br",'accept-language': "zh-CN,zh;q=0.8,en;q=0.6",'user-agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",'content-type': "application/x-www-form-urlencoded; charset=UTF-8",'accept': "application/json, text/javascript, */*; q=0.01",'referer': "https://www.lagou.com/jobs/list_Java?px=new&city=%E6%88%90%E9%83%BD",'x-requested-with': "XMLHttpRequest",'connection': "keep-alive",'x-anit-forge-token': "None",'cache-control': "no-cache",'postman-token': "91beb456-8dd9-0390-a3a5-64ff3936fa63"} response = requests.request("POST", url, data=payload.encode('utf-8'), headers=headers, params=querystring) # print(response.text) hjson = json.loads(response.text) for i in range(15): positionName=hjson['content']['positionResult']['result'][i]['positionName'] companyId = hjson['content']['positionResult']['result'][i]['companyId'] positionId= hjson['content']['positionResult']['result'][i]['positionId'] salary = hjson['content']['positionResult']['result'][i]['salary'] city= hjson['content']['positionResult']['result'][i]['city'] district= hjson['content']['positionResult']['result'][i]['district'] companyShortName= hjson['content']['positionResult']['result'][i]['companyShortName'] education= hjson['content']['positionResult']['result'][i]['education'] workYear= hjson['content']['positionResult']['result'][i]['workYear'] industryField= hjson['content']['positionResult']['result'][i]['industryField'] financeStage= hjson['content']['positionResult']['result'][i]['financeStage'] companySize= hjson['content']['positionResult']['result'][i]['companySize'] job_desc = get_job_desc(positionId) positionName_list.append(positionName) salary_list.append(salary) city_list.append(city) district_list.append(district) companyShortName_list.append(companyShortName) education_list.append(education) workYear_list.append(workYear) industryField_list.append(industryField) financeStage_list.append(financeStage) companySize_list.append(companySize) #job_desc_list.append(job_desc) 4、获取工作信息描述 通过观察发现,打开具体职位的详细页面时,URL 里面的数值(例如下图的 URL 里面的 4789029)就是职位的 positionID,该 positionID 可以通过上一步的职位列表 JSON 返回数据获取。 通过 requests 请求页面信息,再通过 xpath 获取工作描述信息。 def get_job_desc(id): url = "https://www.lagou.com/jobs/"+str(id)+".html" cookie = "JSESSIONID=" + get_uuid() + ";"\"user_trace_token=" + get_uuid() + "; LGUID=" + get_uuid() + "; index_location_city=%E6%88%90%E9%83%BD; " \"SEARCH_ID=" + get_uuid() + '; _gid=GA1.2.717841549.1514043316; ' \'_ga=GA1.2.952298646.1514043316; ' \'LGSID=' + get_uuid() + "; " \"LGRID=" + get_uuid() + "; " headers = {'cookie': cookie,'origin': "https://www.lagou.com",'x-anit-forge-code': "0",'accept-encoding': "gzip, deflate, br",'accept-language': "zh-CN,zh;q=0.8,en;q=0.6",'user-agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",'content-type': "application/x-www-form-urlencoded; charset=UTF-8",'accept': "application/json, text/javascript, */*; q=0.01",'referer': "https://www.lagou.com/jobs/list_Java?px=new&city=%E6%88%90%E9%83%BD",'x-requested-with': "XMLHttpRequest",'connection': "keep-alive",'x-anit-forge-token': "None",'cache-control': "no-cache",'postman-token': "91beb456-8dd9-0390-a3a5-64ff3936fa63"} response = requests.request("GET", url, headers=headers)x = etree.HTML(response.text) data = x.xpath('//*[@id="job_detail"]/dd[2]/div/*/text()')return ''.join(data) 02 数据获取 —— 爬虫 1、设置 cookies 和 headers 如果不设置相关信息,会不允许爬取,返回提示:“您操作太频繁,请稍后再访问”。所以,我们需要设置 headers 和 cookies 信息。 def get_lagou(page,city,kd): url = "https://www.lagou.com/jobs/positionAjax.json" querystring = {"px": "new", "city": city, "needAddtionalResult": "false", "isSchoolJob": "0"} payload = "first=false&pn=" + str(page) + "&kd="+str(kd) cookie = "JSESSIONID=" + get_uuid() + ";"\"user_trace_token=" + get_uuid() + "; LGUID=" + get_uuid() + "; index_location_city=%E6%88%90%E9%83%BD; " \"SEARCH_ID=" + get_uuid() + '; _gid=GA1.2.717841549.1514043316; ' \'_ga=GA1.2.952298646.1514043316; ' \'LGSID=' + get_uuid() + "; " \"LGRID=" + get_uuid() + "; " headers = {'cookie': cookie,'origin': "https://www.lagou.com",'x-anit-forge-code': "0",'accept-encoding': "gzip, deflate, br",'accept-language': "zh-CN,zh;q=0.8,en;q=0.6",'user-agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",'content-type': "application/x-www-form-urlencoded; charset=UTF-8",'accept': "application/json, text/javascript, */*; q=0.01",'referer': "https://www.lagou.com/jobs/list_Java?px=new&city=%E6%88%90%E9%83%BD",'x-requested-with': "XMLHttpRequest",'connection': "keep-alive",'x-anit-forge-token': "None",'cache-control': "no-cache",'postman-token': "91beb456-8dd9-0390-a3a5-64ff3936fa63"} 2、延时设置和分页爬取 避免爬取速度过快被封,设置延时时间为 3-5 秒。通过 for 循环进行分页数据的爬取。 def main(pages,city,job):for n in range(1, pages+1): get_lagou(n,city,job) time.sleep(round(random.uniform(3, 5), 2)) write_to_csv(city,job) 03 数据存储与处理 1、CSV 数据存储 由于数据量不大,最多 450 条数据,采用 CSV 的存储方式。 2、数据处理 ●薪酬数据处理 后续统计月薪的占比,由于薪酬范围是可以自定义范围,没有一个统一的标准。例如薪酬可以是 10k-20k、5k-8k、11k-18k、10k-16k 等情况,后续不利于薪酬范围的可视化,所以将薪酬归纳分类到这几种:2k 以下、2k-5k、5k-10k、10k-15k、15k-25k、25k-50k、50k 以上。 假如薪酬为 10k-20k, 则认为在 10k-15k、15k-25k 这两种归类里面都包含。采用正则表达式进行归类汇总: def salary_categorize(salarys): dict = {'2k以下': 0, '2k-5k': 0, '5k-10k': 0,'10k-15k':0,'15k-25k':0,'25k-50k':0,'50k以上':0} for salary in salarys: if re.match('^[0-1]k-*|.*-[0-1]k$',salary)!=None: dict['2k以下'] += 1 if re.match('^[2-4]k-*|.*-[2-4]k$',salary)!=None: dict['2k-5k'] += 1 if re.match('^[5-9]k-*|.*-[5-9]k$', salary)!=None: dict['5k-10k'] += 1 if re.match('^1[0-4]k-*|.*-1[0-4]k$', salary)!=None: dict['10k-15k'] += 1 if re.match('^1[5-9]k-*|^2[0-4]k-*|.*-1[5-9]k$|.*-2[0-4]k$', salary)!=None: dict['15k-25k'] += 1 if re.match('^2[5-9]k-*|^[3-4][0-9]k-*|.*-2[5-9]k$|.*-[3-4][0-9]k$', salary)!=None: dict['25k-50k'] += 1 if re.match('^[5-9][0-9]k-*|.*-[5-9][0-9]k$|^\d{3,}k-*|.*-\d{3,}k$', salary)!=None: dict['50k以上'] += 1 return dict ●行业信息处理 公司所属行业可以是多个,一般以逗号分隔,但存在部分是以顿号和空格分隔的情况,还有可能存在没有写明相关行业的情况。对此,通过 Python 的 re 库可以处理多个分隔符分隔的数据,所属行业为空,则跳过。 def industryField_counts(csv_file): industryFields = [] d = pd.read_csv(csv_file, engine='python', encoding='utf-8') info = d['industryField'] for i in range(len(info)): try: data = re.split('[,、 ]',info[i]) except: continue for j in range(len(data)): industryFields.append(data[j]) counts = Counter(industryFields) return counts 04 数据可视化与解读 1、公司相关情况分析 从行业情况和公司规模来看,移动互联网占有 40% 的需求,数据服务+大数据+人工智能占了 10% 的比例。Python 非常强大,适合的领域包括 Web 开发、网络编程、爬虫、云计算、人工智能、自动化运维等,所以不管公司规模是大还是小,融资情况如何,都普遍需要 Python 相关的职位的人才。 2、城市需求分析 从上图分析,可以发现,需求量主要集中在中国三大经济圈:京津冀,长三角,珠三角。主要分布在北京(40%)、上海(16%)、深圳(15%)、广州(6%)、成都(6%)和杭州(6%)这 6 个城市。而北京的互联网创业气氛冠绝中国,注册在北京的互联网公司远远高于在其他城市的公司,需求量也是最大的。 3、薪酬与工作经验分析 从工作经验的要求来看,大部分集中在 3-5 年和 1-3 年这两个区间,至于工作经验和薪酬之间的相关性,观察发现,1-3 年工作经验的薪酬普遍在 15-25K,符合正态分布的规律,3-5 年工作经验的薪酬普遍在 15k-25k 和 25k-50k 这两个区间,以 15k-25k 这个区间的居多。达到 5-10 年工作经验的,薪酬在 25k-50K 这个区间的居多。 4、学历要求和工作经验分析 从学历要求来看,大部分都要求至少本科以上,这部分占了约 80% 的比例。所以不要在相信读书无用论这种观点了,学历至少是工作的敲门砖。 工作经验上,普遍要求是 1-5 年,这部分占了 84% 的比例。1年以下和经验不限的,占了约 9%,5-10 年的占了约 7% 的比例。 05 总结 TIOBE 8 月编程语言指数排行榜已经公布了,排名前三的虽然依旧是 Java、C、C++。但 Python 非常接近 TIOBE 索引的前 3 位。Python 这样的上涨趋势,同样可以在 TIOBE 索引排行中体现,互联网业界也开始普遍采用 Python。Python 编程语言最初是 Perl 的继承者,用于编写构建脚本和各种粘合软件。但后来逐渐进入其他领域。如今,在大型嵌入式系统中运行 Python 是很常见的。因此,Python 完全有可能进入前三名,甚至在未来取代 Java 成为新的第一名。 从目前 Python 的就业前景来看,总结如下: ●Python 就业情况乐观,从 TIOBE 8 月编程语言指数排行榜以及百度指数的搜索数来看,Python 的受欢迎程度越来越高。 ●在中国地区,Python 相关职位的需求量,依然集中在三大经济圈,特别是在北京、上海、深圳这几个城市。从行业需求来看,主要集中在移动互联网、数据服务、大数据分析等行业。 ●从拉勾网的数据分析可知,大部分 Python 的相关职位都要求在本科和本科以上,工作经验要求在 1-5 年的居多。因为 Python 在大数据和人工智能领域的爆发性发展, 导致 Python 方向岗位的薪水在水涨船高,从数据分析来看,月薪在 10K-50K 不等。 原文发布时间为:2018-09-3 本文作者:lowelong 本文来自云栖社区合作伙伴“CDA数据分析师”,了解相关信息可以关注“CDA数据分析师”。

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

新功能 | 如何打造一个可用多租户的企业级Maven私有仓库服务

为什么要打造多租户的企业级Maven私有仓库服务? 在Java的世界中,我们通常使用Maven的依赖体系来管理构件(artifact,又称为二方库或三方库)的依赖。Maven仓库用于存储这些构件。一般的远程仓库(比如Maven Central)只提供下载功能。而用户想要管理自己的私有二方库,就只能搭建Maven私服。常用的Maven私服软件有Nexus和Artifactory等。Maven私服是很多企业都需要的功能。 如今云服务越来越深入人心,用户不仅纷纷把自身的服务发布到云端,甚至也会使用云服务来管理自己的整个研发流程。而如果有一个企业级的Maven私有仓库服务,用户只需要简单的开通服务,就可开箱即用,无需自己搭建,免去了维护的烦恼。 现有Maven私库软件的问题 打造这样的服务首先可能会考虑借助已有的一些Maven私库解决方案进行改造

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

直击全球软件供应链成本痛点,Docker EE 助力企业数字化转型

本文首发自“Docker公司”公众号(ID:docker-cn)编译丨小东每周一、三、五 与您不见不散! 捷普集团 (Jabil Group) 是全球三大电子合约制造服务商,成立于1966年,在29个国家拥有100多个网点。他们着手于数字化之旅,使其技术基础设施进行现代化改造,以便公司能够更好地在适当的时间为其全球客户群提供合适的解决方案。 将 .NET 应用进行现代化改造开启数字化之旅 当捷普集团准备着手于数字化之旅时,他们优先考虑到云服务,他们研究了如何以最佳的方式将应用程序迁移到云端。捷普集团通过与 Docker 和 Microsoft 合作,利用 Docker EE 的 Windows Server 2016 和 Microsoft Azure 实现 Docker 现代化传统应用程序(MTA)项目,从监控一个 .NET 4.5应用程序开始到实现整体容器化。 在完成最初的 POC 之后,捷普集团继续将更多的应用程序进行容器化改造,并开始在全球扩大 Docker EE 的使用范围。捷普集团高级 DevOps 工程师 Sujay Pillai 参加了 DockerCon 2018,并在现场分享了捷普集团使用 Docker EE 的一些实践经验。 在降低边缘成本的同时提高应用程序安全性 捷普集团一个日益增长的用例是对生产车间的监控。捷普集团用轻量级的边缘设备来运行监控应用,并使用 Docker EE 将应用程序的容器镜像自动的和安全的交付给设备。这一解决方案使捷普集团能够自动保持这些设备的最新状态,同时也帮助降低了监测站的成本,从每个站的500美元降至50美元,并且极大地节省了能源的开销。 全球规模的开发人员生产力 为了在其全球技术运营中支持容器化,捷普集团还使用 Docker Trusted Registry (DTR)的高速缓存功能进行全球范围的扩展。对于世界各地的网点来说,在新加坡远程办公室中的设备、用户和开发人员可以访问存储在捷普集团主镜像仓库的最新容器镜像,这一点非常重要。尽管目前使用的容器镜像非常小,但是随着越来越多的设备和用户拉取镜像,捷普集团正在着手降低网络延迟和提升网络能力。 捷普集团一直在寻找优化运营的方法,以便为客户提供更好、更快的服务。公司正在对其基础设施进行批判性的审视,并确定公司哪些部分可以实现现代化或可精简的地方,以便更好地实现数字化转型。 如果想了解更多相关信息,请观看以下演示视频: Docker 官方微信公众号入口:http://t.cn/RdsDdJA

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

吴韧谈异构智能芯片:比谷歌能耗低,比华为寒武纪计算力

本文来自AI新媒体量子位(QbitAI) 昨天的媒体交流会上,吴韧全程带笑。 和气、稳重是吴韧给人留下的第一印象。自2015年百度离职创立异构智能以来,这位CEO很少出来发声,异构智能也因此被打上了“神秘”的标签。 与其说这场名为《异构智能拥抱人工智能大势》的分享是场媒体交流会,倒不如说是场吴韧揭秘他与异构智能近况的恳谈。 “异构智能有芯片、模型,有超级计算机,希望将模型脱离云端,带到本地和终端,让终端变得智能。”吴韧一开始就表达了公司愿景。 △Novumind(异构智能)创始人兼CEO吴韧博士(右),及先烽资本创始人廖志宇(左) 智能终端 “(云端)物联网是个伪命题,是难以实现的。”吴韧说。 目前的现状是,看似魔术般连接起来的物联网,实际需要通过很多海底和底下光缆从分支道路连接到主干道。接入的分支道路呈指数级增长,已经远远超出主干道增长的速度

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

搭建一个可用负载均衡的集群架构(第三部分)

1.使用脚本编写一个简单的文件分发系统即可,首先expect编写一个脚本文件rsync.expect,这个脚本是实现文件同步的脚本,内容如下: expect编写一个脚本文件rsync.expect,这个脚本是实现文件同步的脚本,内容如下: [root@localhost ~/syncList]# vim syncFile.expect #!/usr/bin/expect set host [lindex $argv 0] set file [lindex $argv 1] set passwd [lindex $argv 2] # 核心命令,同步多个文件 spawn rsync -avR --files-from=$file / root@$host:/ expect { "yes/no" { send "yes\r"} "password:" { send "$passwd\r" } } expect eof [root@localhost ~/syncList]# chmod a+x syncFile.expect 提示:如果你的rsync命令没有加-R选项的话,就需要确保目标机器也有这个文件列表中所定义的目录路径,不然就会报错。而且存放文件路径列表的文件内容不能有空格,不然会把这个空格看作为文件路径的一部分。 2.然后再编辑一个文本文件,这个文件用来放需要同步的文件列表,例如我这里需要同步以下几个文件: [root@localhost ~/syncList]$ cat /tmp/fileList.txt /usr/local/nginx/conf/vhost/dedecms.com.conf /usr/local/nginx/conf/vhost/discuz.com.conf /usr/local/nginx/conf/vhost/zrlog.com.conf /usr/local/sbin/nginx_log_rotate.sh /var/spool/cron/root [root@localhost ~/syncList]$ 3.还需要编辑一个ip.txt文件,用于存放需要同步的目标机器的IP地址,例如我需要将文件都同步这几个IP的机器上: [root@localhost ~/syncList]$ cat /root/webServerIP.txt 192.168.200.153 192.168.200.154 192.168.200.155 192.168.200.156 192.168.200.157 192.168.200.158 192.168.200.159 192.168.200.160 4.再编写一个shell脚本syncFile.sh,这个脚本比较简单,只是遍历出ip.list文件内容然后交给syncFile.expect脚本去执行而已,示例: #!/bin/bash ipList="$1" fileList="$2" password="$3" for ip in `cat $ipList` do # 第二个参数就是需要同步的文件列表 ./syncFile.expect $ip $fileList $password done 5.最后我们只需要执行syncFile.sh脚本即可实现批量同步多个文件: [root@localhost ~/syncList]$ sh ./syncFile.sh "/root/webServerIP.txt" "/tmp/fileList.txt" "lri35krJF;ba" 我运行完之后,没有报错,文件也正常同步了,这样我们就实现了一个简单的文件分发系统,这个需求就实现了。 11 制定合理的mysql数据备份方案,并写备份脚本,要求把备份数据传输到备份服务器 这个mysql的主从已经可以满足备份的需求了,如果需要通过脚本另外备份,可以参考以下代码: 假定,我们知道mysql root账号的密码,要备份的库为discuz,本地备份目录为/bak/mysql, 远程服务器ip为192.168.123.30,远程提供了一个rsync服务,备份的地址是 192.168.200.149::backup . 写完脚本后,需要加入到cron中,每天凌晨3点执行。 #! /bin/bash ### backup mysql data PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/mysql/bin d1=`data +%w` d2=`date +%d` pass="123456" bakdir=/bak/mysql r_bakdir=192.168.200.149::module/data/mysqlBackup exec 1>/var/log/mysqlbak.log 2>/var/log/mysqlbak.log echo "mysql backup begin at `date +"%F %T"`." mysqldump -uroot -p$pass –default-character-set=utf8 ultrax >$bakdir/ultrax$d1.sql mysqldump -uroot -p$pass –default-character-set=utf8 DedeCMS >$bakdir/DedeCMS$d1.sql mysqldump -uroot -p$pass –default-character-set=utf8 zrlog >$bakdir/zrlog$d1.sql rsync -az $bakdir/ultrax$d1.sql $r_bakdir/ultrax$d2.sql rsync -az $bakdir/DedeCMS$d1.sql $r_bakdir/DedeCMS$d2.sql rsync -az $bakdir/zrlog$d1.sql $r_bakdir/zrlog$d2.sql echo "mysql backup end at `date +"%F %T"`." 接着加入cron: 0 3* /bin/bash /usr/local/sbin/mysqlbak.sh 然后就会每天凌晨3点进行备份了。 12 制定代码、静态文件的备份方案,并写备份脚本,要求备份13 编写数据恢复文档,能保证当数据丢失在2小时内恢复所有数据 以上这两个需求可以一起实现,结合起来就是两个小时同步一次文件,因为提到需要恢复所有数据,所以需要备份整个站点目录,备份的脚本修改一下分发系统那个expect脚本就可以了,代码如下: [root@localhost ~]$ vim syncList/syncWebFile.expect #!/usr/bin/expect set host [lindex $argv 0] set file [lindex $argv 1] set passwd [lindex $argv 2] spawn rsync -az $file root@$host:$file expect { "yes/no" { send "yes\r"} "password:" { send "$passwd\r" } } interact [root@localhost ~]$ chmod a+x /root/syncList/syncWebFile.expect ## shell 脚本 [root@localhost ~]$ vim /root/syncList/webBak.sh #!/bin/bash ip="$1" webDir="$2" password=`cat /etc/sync.passwd` d=`date +%F" "%T` echo "webdir backup begin at `date +"%F %T"`." for dir in `cat $webDir` do /root/syncList/syncWebFile.expect $ip $dir $password done echo "backup = ip:$ip time:$d;" >> /tmp/webSync.log echo "webdir backup end at `date +"%F %T"`." 创建密码文件: [root@localhost ~]$ vim /etc/sync.passwd lri35krJF;ba [root@localhost ~]$ chmod 600 /etc/sync.passwd 创建文件存放需要同步的目录路径列表: [root@localhost ~]$ vim /tmp/webDir.txt /data/wwwroot/discuz.com /data/wwwroot/dedecms.com /data/wwwroot/zrlog.com 在备份服务上创建目录: mkdir -p /data/wwwroot/ 8.测试一下能否进行同步: [root@localhost ~]$ /bin/bash /root/syncList/webBak.sh "192.168.200.149" "/tmp/webDir.txt" webdir backup begin at 2017-12-22 16:53:07. spawn rsync -az -e ssh -i .ssh/id_rsa /data/wwwroot/discuz.com user1@192.168.200.149:/data/wwwroot/discuz.com Enter passphrase for key '.ssh/id_rsa': spawn rsync -az -e ssh -i .ssh/id_rsa /data/wwwroot/dedecms.com user1@192.168.200.149:/data/wwwroot/dedecms.com Enter passphrase for key '.ssh/id_rsa': spawn rsync -az -e ssh -i .ssh/id_rsa /data/wwwroot/zrlog.com user1@192.168.200.149:/data/wwwroot/zrlog.com Enter passphrase for key '.ssh/id_rsa': webdir backup end at 2017-12-22 16:53:16. [root@localhost ~]$ 9.执行完脚本后到备份服务器上确认一下: [root@localhost ~]$ ls /data/wwwroot/ dedecms.com discuz.com zrlog.com [root@localhost ~]$ ls /data/wwwroot/dedecms.com/ dedecms.com [root@localhost ~]$ ls /data/wwwroot/dedecms.com/dedecms.com/ a data dede favicon.ico images include index.php logs m member plus robots.txt tags.php templets uploads [root@localhost ~]$ ls /data/wwwroot/zrlog.com/zrlog.com/ admin assets attached error favicon.ico include install logs META-INF WEB-INF [root@localhost ~]$ ls /data/wwwroot/discuz.com/discuz.com/ admin.php api.php config cp.php data fileList.txt forum.php home.php member.php plugin.php robots.txt source template uc_server api archiver connect.php crossdomain.xml favicon.ico filePermission.sh group.php index.php misc.php portal.php search.php static uc_client userapp.php [root@localhost ~]$ 10.看看日志文件里有没有记录每次同步的时间: [root@localhost ~]$ cat /tmp/webSync.log backup = ip:192.168.200.149 time:2017-12-22 17:13:18; [root@localhost ~]$ 11.添加到任务计划里: 0 */2 * * * /bin/bash /root/syncList/webBak.sh "192.168.200.149" "/tmp/webDir.txt" 7 所有服务器要求只能普通用户登录,而且只能密钥登录,root只能普通用户sudo 1.首先使用visudo命令编辑配置文件,设置用户的alias: User_Alias ADMINS = user1, user2, user3 然后批量执行useradd命令在全部服务器上添加user1、user2、user3用户 2.找到Allow root to run any commands anywhere,在这行下面添加以下内容: ADMINS ALL=(ALL) NOPASSWD: /usr/bin/su, /usr/bin/ls, /usr/bin/cat, /usr/bin/mkdir 3.修改sshd.config配置文件,修改以下内容: [root@localhost ~]$ vim /etc/ssh/sshd_config PermitRootLogin no PubkeyAuthentication yes PasswordAuthentication no 重启服务: systemctl restart sshd.service 4.新建/root/.ssh 文件夹,然后生成密钥 [root@localhost ~]$ mkdir /root/.ssh/ [root@localhost ~]$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): # 直接回车 Enter passphrase (empty for no passphrase): # 设置密钥的密码 Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: 95:e1:79:b3:a0:4b:a0:d8:83:77:4e:88:96:8b:af:56 root@localhost.localdomain The key's randomart image is: +--[ RSA 2048]----+ | . | | . + | | . * o | | * o . o o o | | * * o S . | | o E = . . | |. o . . | | o | |o.. | +-----------------+ [root@localhost ~]$ 查看生成的密钥文件: [root@localhost ~]$ cd .ssh/ [root@localhost ~/.ssh]$ ls id_rsa id_rsa.pub [root@localhost ~/.ssh]$ 把公钥的文件名修改成authorized_keys,并复制一份到user1用户的家目录下: mv id_rsa.pub authorized_keys mkdir /home/user1/.ssh/ touch /home/user1/.ssh/authorized_keys cat /root/.ssh/authorized_keys > /home/user1/.ssh/authorized_keys 设置权限: chmod 700 /home/user1/.ssh/ chmod 600 /home/user1/.ssh/authorized_keys chown -R user1:user1 /home/user1/.ssh/ 5.将id_rsa文件下载到本地。 6.连接时选择这个文件,或者导入Xshell中: 登录成功: 7.然后把/etc/sudoers、/etc/ssh/sshd_config配置文件同步到所有机器上,密钥也一并同步,同步完之后记得重启sshd服务。 完成以上操作后,无论使用密钥或者是密码都无法远程登录root用户,只能登录普通用户了。 因为我们禁止了root远程登录,并且普通用户也只能密钥登录,所以之前写的那个备份文件的脚本需要进行更改,改成通过ssh指定密钥进行连接远程机器。 1.给刚刚生成的密钥文件授予700权限: chmod 700 .ssh/id_rsa 2.使用ssh测试一下看看能否进行同步文件(user1的密钥文件我已经同步到所有机器上了): [root@localhost ~]$ rsync -av -e "ssh -i .ssh/id_rsa" /tmp/fileList.txt user1@192.168.200.149:/tmp/fileList.txt Enter passphrase for key '.ssh/id_rsa': ## 这是生成密钥时设置的密码 sending incremental file list fileList.txt sent 269 bytes received 31 bytes 28.57 bytes/sec total size is 189 speedup is 0.63 [root@localhost ~]$ 从结果可以看到,能够成功同步文件。 好,接下来修改之前的脚本,首先修改的是密码文件,将之前的登录密码改为生成密钥时设置的密码: [root@localhost ~]$ vim /etc/sync.passwd 123456 [root@localhost ~]$ shell脚本不用修改,修改expect脚本如下: [root@localhost ~]$ vim syncList/syncWebFile.expect #!/usr/bin/expect set host [lindex $argv 0] set file [lindex $argv 1] set passwd [lindex $argv 2] spawn rsync -az -e "ssh -i .ssh/id_rsa" $file user1@$host:$file expect { "yes/no" { send "yes\r"} "'.ssh/id_rsa':" { send "$passwd\r" } } expect eof 到备份服务器上给/data/wwwroot/目录授予777权限: chmod 777 /data/wwwroot/ 然后测试一下该脚本: [root@localhost ~]$ /bin/bash /root/syncList/webBak.sh "192.168.200.149" "/tmp/webDir.txt" webdir backup begin at 2017-12-22 16:53:07. spawn rsync -az -e ssh -i .ssh/id_rsa /data/wwwroot/discuz.com user1@192.168.200.149:/data/wwwroot/discuz.com Enter passphrase for key '.ssh/id_rsa': spawn rsync -az -e ssh -i .ssh/id_rsa /data/wwwroot/dedecms.com user1@192.168.200.149:/data/wwwroot/dedecms.com Enter passphrase for key '.ssh/id_rsa': spawn rsync -az -e ssh -i .ssh/id_rsa /data/wwwroot/zrlog.com user1@192.168.200.149:/data/wwwroot/zrlog.com Enter passphrase for key '.ssh/id_rsa': webdir backup end at 2017-12-22 16:53:16. [root@localhost ~]$ 可以看到没有报错,同步成功,到备份服务器上看看: [root@localhost ~]$ ls /data/wwwroot/ dedecms.com discuz.com zrlog.com [root@localhost ~]$ ls /data/wwwroot/dedecms.com/ dedecms.com [root@localhost ~]$ ls /data/wwwroot/dedecms.com/dedecms.com/ a data dede favicon.ico images include index.php logs m member plus robots.txt tags.php templets uploads [root@localhost ~]$ ls /data/wwwroot/zrlog.com/zrlog.com/ admin assets attached error favicon.ico include install logs META-INF WEB-INF [root@localhost ~]$ ls /data/wwwroot/discuz.com/discuz.com/ admin.php api.php config cp.php data fileList.txt forum.php home.php member.php plugin.php robots.txt source template uc_server api archiver connect.php crossdomain.xml favicon.ico filePermission.sh group.php index.php misc.php portal.php search.php static uc_client userapp.php [root@localhost ~]$ 没毛病 ,到目前为止这个项目就告一段落了,其中有一些细节还需慢慢处理,这些都是日后维护的问题了。 本文转自 ZeroOne01 51CTO博客,原文链接:http://blog.51cto.com/zero01/2052429,如需转载请自行联系原作者

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

【IOS】仿糗事百科客户端(基本实现了除注册,评论之外的功能)

一直挺喜欢看糗事百科的,所以最近写了一个 iphone版的客户端,自己用着玩,图片资源是扒的官方的。基本实现了除了登陆评论之外的功能,接口是找到了,但是用不来这个接口。。。囧。。 下面是最终实现的demo的截图: 下面把源码和大家分享一下: http://download.csdn.net/detail/toss156/4381732 仅供学习交流使用,禁止商用,素材版权归糗事百科所有。。 本文转蓬莱仙羽51CTO博客,原文链接:http://blog.51cto.com/dingxiaowei/1366202,如需转载请自行联系原作者

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

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

用户登录
用户注册