Bootstrap

大数据概论

大数据概论
高速发展的信息时代,新一轮科技革命和变革正在加速推进,技术创新日益成为重塑经济发展模式和促 进经济增长的重要驱动力量,而大数据无疑是核心推动力。
大数据不是一项专门的技术,而是很多技术的综合应用,大数据代表的一种理念、一种解决问题的思 维、一系列技术的集合。可以通过一系列大数据技术对海量数据进行分析,挖掘出数据背后的价值。大数据是指无法在一定时间内用常规软件工具对其内容进行抓取、管理和处理的体量和类别特别大的数 据集合
概述大数据
大数据 big data 指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新 处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。
大量数据资源为解决以前不可能解决的问题带来了可能性。
大数据不一定存储于固定的数据库,而是分布在不同的网络空间
大数据以半结构化或非结构化数据为主,具有较高的复杂性
大数据注重的是全量样本数据而不是局部数据,注重相关性而不是因果关系,通过分析和数据挖掘
将其转化为知识,再由知识提炼成智慧以获取洞察。
大数据的 4 个特点,数据量大 Volume 、数据类型繁多 Variety 、速度快 Velocity 和价值密度低 Value
大数据技术是发现大规模数据中的规律,通过对数据的分析、发现,从而实现对决策层决策提供支持, 实现商业价值,所以大数据发展的最终目标还是挖掘其应用价值,没有价值或者没有发现其价值的大数 据从某种意义上讲是一种冗余和负担。
存储设备容量不断增加
单位存储空间价格不断降低,开始倾向于将更多的数据保存下来
数据量单位:字节 B KB MB GB TB PB EB ZB
CPU 处理能力大幅提升
摩尔定律: CPU 性能大约每隔 18 个月提高一倍,价格下降一半 网络带宽不断增加
4G(100Mbps)---5G(1Gbps)
大数据的一般流程:数据采集接入 --- 数据清洗 --- 数据融合 --- 数据分析挖掘 --- 数据可视化 --- 运营维护
大数据相关的技术从执行流程上可以大致分为数据收集、数据存储、资源管理、计算框架、数据分析和
数据展示 6 个方面。
数据产生的方式
运营式系统阶段:数据库技术的出现,数据的产生方式是被动的,实际业务产生则生成数据
用户原创内容阶段: web2.0 技术的发展,自服务为主,用户本身就是内容的生成者
感知式系统阶段:物联网技术的发展
大数据应用场景
物流仓库:大数据分析系统助理商家精细化运营、提升质量、节约成本
零售:分析用户习惯,为用户购买商品提供方便,从而提供商品销量。经典案例:纸尿裤 + 啤酒
旅游:深度结合大数据能力与旅游行业需求,共建旅游行业智慧管理、智慧服务和智慧营销的未来
商品广告推荐:给用户推荐可能喜欢的商品。案例:用户买了一本书,又推荐了若干本书
个人信息保护法草案三审。草案进一步完善个人信息处理规则,特别是对应用程序 APP 过度收
集个人信息、 大数据杀熟 等作出有针对性规范
房产:大数据全面助力房地产行业,打造精准投策与营销,选出更合适的地,建造更合适的楼,卖
给更合适的人
保险:海量数据挖掘及风险预测,助力保险行业精准营销,提升精细化定价能力
金融:多维度体现用户特征,帮助金融机构推荐优质客户,防范欺诈风险
人工智能
大数据开发总体架构
大数据产业是指一切与支撑大数据组织管理和价值发现相关的企业经济活动的集合。大数据产业包括 IT基础设施层、数据源层、数据管理层、数据分析层、数据平台层和数据应用层
1 、数据来源层。 MySQL 数据库、文件日志半结构化数据、视频 PPT 非结构化数据
2 、数据传输层。 Flume 数据采集、 Sqoop 数据迁移、 Kafka 消息队列
3 、数据存储层。 ElasticSearch 全文检索、 HBase 非关系型书库、 HDFS 文件存储
4 、资源管理层。 YARN 资源管理
5 、数据计算层。 MapReduce 离线计算、 Flink Core 内存计算
6 、任务调度层。 Crontab 定时任务和 Oozie 任务调度
7 、业务模型层。数据可视化和业务逻辑处理
大数据部门组织结构
大数据架构设计用来处理对传统数据库系统而言太大或太复杂的数据的引入、处理和分析。组织进入大 数据领域的门槛各不相同,具体取决于用户的权限及其工具的功能。对某些组织来说,大数据可能意味着数百个GB 的数据,而对另一些组织来说,大数据则意味着数百个 TB 的数据。随着处理大数据集的工具 的发展,大数据的涵义也在不断地变化
业务流程分析
大数据的影响
1 、图灵奖获得者、著名数据库专家 Jim Gray 博士观察并总结人类自古以来,在科学研究上,先后历经了 实验、理论、计算和数据四种范式。
范式 1 :实验科学使用实验的方式解决科学问题
范式 2 :理论科学采用数学、几何、物理等理论构建问题模型和寻找解决方案
范式 3 :计算科学借助计算机的高速运算能力解决各种问题
范式 4 :数据科学一切以数据为中心,从数据中发现问题、解决问题,真正体现数据的价值
2 、在思维方面,大数据完全颠覆了传统的思维方式:全样而非抽样、效率而非精确、相关而非因果
3 、在社会发展方面,大数据决策逐渐成为一种新的决策方式,大数据应用有力促进了信息技术与各行各 业的深度融合,大数据开发大大推动了新技术和新应用的不断涌现。
4 、在就业市场方面,大数据的兴起使得数据科学家称为热门职业。在人才技术方面,大数据的兴起将在 很大程度上改变中国高校信息相关专业的现有教学和科研体制。
大数据的计算模式
大数据处理包括数据收集、数据存储、资源管理、计算框架、数据分析和数据展示 6 部分,常见的 4 种计
算模式有:
批量处理:离线计算,针对大规模历史数据的批量处理,例如 MapReduce
流计算:针对流数据的实时计算,例如 Storm
图计算:针对大规模图结构的处理,常用于社交网络,如 GraphX
查询分析:主要针对大规模数据的存储管理和查询分析,例如 Hive Cassandra
注意:批处理数据不能实时计算,但是批处理的逻辑可以非常的复杂;实时流处理的数据可以实时计 算,但是计算逻辑相对比较简单
离线批处理,特点:使用历史数据,大批量的处理,要求吞吐率。
实时交互式处理,特点:用户交互使用,要求反映速度在秒级到数分钟之间。 大数据计算模式
解决问题
代表产品
批处理计算
针对大规模数据的批量处理
MapReduce Spark 等流计算
针对流数据的实时计算
Storm S4 Spark Streams Flink 等图计算
针对大规模图结构数据的处理
Pregel GraphX 等查询分析计算
大规模数据的存储管理和查询分析
Hive Cassandra Impala
流式数据处理,特点:数据以流的形式输入,要求毫秒级的处理速度,且处理后的数据大部分都不
用储存 大数据应用结构举例
一般网站把用户的访问行为已 Apache 日志形式记录下来,其中包括 client_ip user_id access_time 、 url、 referer status page_size agent 等,因为须统一对数据进行离线分析,所以常将其全局移到同一位置。
1kw/ 天网站请求数,每天日志 450B/ *1kw=4.2G ,日志存储周期 2 年, 2 年需要 3.0T
解决方案:
为方便系统查看日志,不压缩需要 3T 空间
为避免系统盘影响服务器使用,对系统盘左 RAID1
为避免其他存放数据的盘损坏导致数据无法恢复,对剩余盘作 RAID5
所有数据都汇聚到这几台 LogBackup 服务器。在这套架构上就可以离线统计,如 wc grep sort 等系统 命令就可以完成很多统计,如统计访问频率较高的client_ip
阶段 时间 内容
第一阶段萌芽期上世纪90年代至本世纪初
随着数据挖掘理论和数据库技术的逐步成熟,一批商业智能工具和知识管理技
术开始被应用,如数据仓库、专家系统、知识管理等。
第二阶段成期 本世纪前十年
Web2.0 应用迅猛发展,非结构化数据大量产生,传统处理方法难以应对,带动
了大数据技术的快速突破,大数据解决方案逐渐走向成熟,形成了并行计算与
分布式系统两大核心技术,谷歌的 GFS MapReduce 等大数据技术收到追捧,
Hadoop 平台开始大行其道
第三阶段: 大规模应用期2010年以后
大数据应用渗透各行各业,数据驱动决策,信息社会智能化程度大幅提高
大数据的发展历程
大数据相关技术
大数据技术是发现大规模数据中的规律,通过对数据的分析实现对运营层决策的支持。本质简单的说就是发现数据规律,实现商业价值。大数据技术面对的是大规模数据,不是使用Excel 就可以进行数据分析的数量,而且每天还会有大批量数据的产生。
JAVA => 面向对象编程语言。 Hadoop 的源代码是基于 Java 语言编写的,但是由于 Hadoop 的部分功能对Linux 操作系统有一定的依赖,所以 Hadoop 对其它平台的兼容性不是很好
Linux => Unix 操作系统
linux 是一套免费使用和自由传播的以网络为核心设计思想的类 Unix 操作系统,是一个基于 POSIX
Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统,能运行主要的 unix 工具软件、应用软件
和网络协议 Hadoop 生态圈
HDFS => 解决分布式存储问题
MapReduce => 解决分布式并行计算问题
Yarn => 应用资源协调者
Zookeeper => 分布式应用程序协调服务
Flume => 分布式日志收集系统
Hive => 基于 Hadoop 的数据仓库工具,将结构化的数据文件映射为一张数据库表并提供 SQL 查询功能,能转变为MapReduce 任务来执行。 Hive 能实现快速 MapReduce 统计而不必开发专门的
MapReduce 应用程序。十分适合数据仓库的统计分析。
HBase => 分布式、面向列的开源数据库,适合非结构化数据存储。
Sqoop => 数据传递工具
Spark => 目前企业常用的微批处理离线 / 实时计算引擎。
Scala => 多范式编程语言、面向对象和函数式编程的特性
Flink => 目前最火的流处理框架、既支持流处理、也支持批处理。基本上彻底替换了 storm Elasticsearch => 大数据分布式弹性搜索引擎
离线 / 实时项目 => 简历中最好两个,一个是电信的,一个是电商的,应该随着市场的变化不断的实时更新
大数据的关键技术 功能
数据采集
利用 ETL 工具将分布的、异构的数据源中的数据如关系数据、平面数据文件等,抽取到临时
中间层后进行清洗、转换、集成,最后加载到数据仓库或数据集市中,成为联机分析处理、
数据挖掘的基础;或者也可以把实时采集的数据作为流计算系统的输入,进行实时处理分析
数据存储和管理
利用分布式文件系统、数据仓库、关系数据库、 NoSQL 数据库、云数据库等,实现对结构
化、半结构化和非结构化海量数据的存储和管理
数据处理与分析
利用分布式并行编程模型和计算框架,结合机器学习和数据挖掘算法,实现对海量数据的处
理和分析;对分析结果进行可视化呈现,帮助人们更好的理解数据、分析数据
数据隐私和安全
在从大数据中挖掘潜在的巨大商业价值和学术价值的同时,构建隐私数据保护体系和数据安
全体系,有效保护个人隐私和数据安全
就业要求
熟悉 Hadoop MPPDB 等相关技术
熟悉 Hbase Hive MR Spark Solr storm flink MapReduce Kafka Redis
Elasticsearch 技术
至少精通 1 种主流数据库技术( Oracle/MySQL/SQL server
至少精通 1 门开发语言( JAVA/Python/Scala/Shell
MPP 即大规模并行处理 Massively Parallel Processor 。在数据库非共享 shared nothing 集群中,每个节点都有独立的磁盘存储系统和内存系统,业务数据根据数据库模型和应用特点划分到各个节点上,每台数据节点通过专用网络或者商业通用网络互相连接,彼此协同计算,作为整体提供数据库服务。非共享数据库集群有完全的可伸缩性、高可用、高性能、优秀的性价比、资源共享等优势。Elasticsearch 就是一种 MPP 架构的数据库,把小数据库组织起来,联合成一个大型数据库。将数据分片,存储在每个节点上。每个节点仅查询自己的数据。所得到的结果再经过主节点处理得到最终结果。通过增加节点数目达到系统线性扩展。
大数据与云计算、物联网
云计算、大数据和物联网代表了 IT 领域最新的技术发展趋势,三者相辅相成,既有联系又有区别。
云计算实现了通过网络提供可伸缩的、廉价的分布式计算能力,用户只需要在具备网络接入的条件
的地方,就可以随时地获得所需要的各种 IT 资源。重点在于底层基础 IT 资源的整合优化
以服务的方式提供的 IT 资源的商业模式有基础设施即服务 IaaS 、平台即服务 PaaS 和软件即服
SaaS 三种, IaaS 将基础设施,即计算资源和存储作为服务出租; PaaS 把平台作为服务出
租; SaaS 把软件作为服务出租。
云计算包括公有云、私有云和混合云三种类型。公有云面向所有注册付费的用户提供服务,例
如阿里云;私有云只向特定用户提供服务,一般只为企业内部提供服务;混合云是私有云和公
有云的综合
物联网是物物相连的互联网,是互联网的延伸,它利用局部网络或互联网等通信技术把传感器、控
制器、机器、人员和物等通过新的方式联在一起,形成人与物、物与物相联,实现信息化和远程管
理控制物联网从技术架构上可以分为采集数据的感知层、信息传输的网络层、存储数据和处理数据的
处理层和功能综合和数据展示的应用层。
大数据主要解决,海量数据的采集、存储和分析计算问题 云计算的定义有很多,广泛接受的是美国国家标准与技术研究院所定义的,即云计算是一种按网络
使用量付费的便捷模式,能进入可配置的计算资源共享池(资源包括网络、服务器、存储、应用软
件和服务),使资源被利用。
云计算是硬件资源的虚拟化后再分配使用,相当于计算机和操作系统,以更大限度的发挥网络的资
源优势。大数据是海量数据的高效处理,相当于传统的数据库。大数据与云计算是一种不可分的、
相互依存的关系。云计算作为计算资源的底层,支撑上层的大数据处理,大数据的趋势是实时交互
式的查询效率和分析能力。
云计算核心是虚拟化,主要概念在于资源池化,提高资源的利用回报。若 CPU 利用率达到 70-80%
则虚拟化没有任何意义。如 VMWare 重点在于切分。而 Hadoop 可使用多个物理设备资源,重点在
于聚合。
物联网是建立在互联网基础上实现的物物相连的互联网,主要有 3 项关键技术,即传感器技术、无
线射频识别 RFID 和嵌入式系统技术。物联网是大数据(设备数据)的来源,大数据技术为物联网
数据的分析提供有力的支撑,云计算为物联网提供了海量数据存储能力,大数据为云计算所产生的
运营数据提供分析和决策支持。
概述 ETL
ETL 即数据抽取、转换和加载。 ODS 操作性数据、 DW 数据仓库、 DM 数据集市
数据抽取
数据抽取是指把 ODS 源数据抽取到 DW 中,然后处理成展示给相关人员查看的数据
源数据:用户访问日志、自定义事件日志和操作日志、业务日志、系统日志、监控日志、其它日志等
抽取频次:
如果没有特殊要求可以一天一次,但是需要避开拉去日志的高峰期
对于有实时性要求的日志,可以一小时一次或者直接使用 kafka 等相关工具收集,需要考虑到系统
能否承受
抽取策略:
由于数据量较大,一般都是采用增量抽取,但是对于一些特殊场景的数据,比如订单数据,由于订
单的状态会发生变化,并且订单的量级是可预知和相对较少的,就需要采用全量拉取的策略
对于增量拉取的日志,如果是文件类型,可以在文件名称上追加日期,例如
server_log_2018082718.log ,这样就可以满足按小时拉取的需求
对于源数据的保留,考虑到突发情况,服务器上的源数据至少要保证 2 天以上的时间 数据转换、清洗
数据转换清洗就是把不需要的和不符合规范的数据进行处理。数据清洗最好不要放在抽取的环节进行,
考虑到有时可能会查原始数据。一般各公司都会有自己的规范。
数据清洗主要包括以下几个方面:
空值处理;根据业务需要,可以将空值替换为特定的值或者直接过滤掉;
验证数据正确性;主要是把不符合业务含义的数据做一处理,比如,把一个表示数量的字段中的字
符串替换为 0 ,把一个日期字段的非日期字符串过滤掉等等;
规范数据格式;比如,把所有的日期都格式化成 yyyy-MM-dd HH:mm:ss 的格式等;
数据转码;把一个源数据中用编码表示的字段,通过关联编码表,转换成代表其真实意义的值等
等;
数据标准统一;比如在源数据中表示男女的方式有很多种,在抽取的时候,直接根据模型中定义的
值做转化,统一表示男女;
其他业务规则定义的数据清洗 ...
数据加载
数据拉取,清洗完之后,就需要展示。一般是把清洗好的数据加载到 mysql 中,然后在各系统中使用或 者使用Tableau 直接给相关人员展示
ETL 相关工具
ELT 相关的工具有很多,这里只列举一些常用的,而且各公司的技术原型也不一样,就需要根据实际情
况来选择
数据抽取工具: kafka flume sync
数据清洗工具: hive/tez pig/tez storm spark
其它工具
数据存储: hadoop hbase ES redis
任务管理: azkaban oozie
数据同步: datax sqoop
ETL 过程中的元数据
元数据管理系统对于数据仓库来说是必须的,并且相关人员必须定时维护,如果元数据和数据仓库中的
变动不同步,那么元数据系统就形同虚设。
对于元数据管理不应该是规范,应该是硬性规定。
大数据和人工智能
人工智能和大数据是紧密相关的两种技术,二者既有联系,又有区别。
人工智能是一种计算形式,它允许机器执行认知功能,例如对输入起作用或作出反应,类似于人类
的做法,而大数据是一种传统计算,它不会根据结果采取行动,只是寻找结果
二者要达成的目标和实现目标的手段不同。大数据主要目的是通过数据的对比分析来掌握和推演出
更优的方案。就拿视频推送为例,我们之所以会接收到不同的推送内容,便是因为大数据根据我们
日常观看的内容,综合考虑了我们的观看习惯和日常的观看内容;推断出哪些内容更可能让我们会
有同样的感觉,并向将其推送给我们。而人工智能的开发,则是为了辅助和代替我们更快、更好地
完成某些任务或进行某些决定。不管是汽车自动驾驶、自我软件调整亦或者是医学样本检查工作,
人工智能都是在人类之前完成相同的任务,但区别就在于其速度更快、错误更少,它能通过机器学
习的方法,掌握我们日常进行的重复性的事项,并以其计算机的处理优势来高效的达成目标。
虚拟机安装 常见的虚拟机软件有 VMware Workstation (简称 VMware )、 VirtualBox Microsoft Virtual PC 等,
其中 VMware 市场占有率最高
VMware Workstation 是一款功能强大的桌面虚拟计算机软件。可以在一台机器上同时运行二个或更多Windows、 DOS Linux 系统。与多启动系统相比, VMWare 采用了完全不同的概念。多启动系统在一个时刻只能运行一个系统,在系统切换时需要重新启动机器
安装虚拟机为 CentOS7 64
1 、修改最大磁盘大小从默认的 20G 修改为 200G (一次性修改的大一些,集群运行的过程中会产生大量文件,默认20G 不够用)
2 、建议选择内存为 2048 ,即调整虚拟机内存为 2G
3 、建议 CPU ,选择处理器数量和内核数量均为 2
4 、安装完成后创建快照
磁盘快照是虚拟机磁盘文件 VMDK 在某个点及时的复本。系统崩溃或系统异常可通过使用恢复到快照来 保持磁盘文件系统和系统存储。当升级应用和服务器及给它们打补丁的时候,快照是救世主。VMware快照是VMware Workstation 里的一个特色功能。
5 、创建完快照后启动虚拟机 , 使用 root 用户和 root 密码登录系统
6 、停止防火墙
停止防火墙: systemctl stop firewalld
禁止防火墙随着系统启动而启动: systemctl disable firewalld 查看防火墙状态: systemctl status firewalld
7 、禁用 selinux
vi/etc/selinux/config ,然后将 SELINUX 的值设置为 disabled
查看是否设置完成 cat /etc/selinux/config
8 、配置虚拟机网络
host-only 宿主机和 linux 客户机单独组网,必须同一个网段启动对应虚拟网卡,不能访问宿主机所
在网段的其它设备,好处在于网络隔离,缺点是虚拟机不能与其它机器通讯
bridge 桥接模式,宿主机与客户机在同一局域网中,在同一个局域网中设备可以互相访问,但不安
全。无需虚拟网卡,但是不能与局域网中设备 IP 冲突
NAT 网络地址转换, NAT 模式的虚拟机就是通过宿主机上网和交换数据的。所有的虚拟机构成了一
个局域网,宿主机就是这些虚拟机的上网网关,这样有个好处,宿主机的地址变化了,虚拟机的地
址不用改。
8.1 、打开虚拟网络编辑器
8.2 、设置虚拟网络和子网,选择 VMnet8 点击更改设置
选择 VMnet8 ,子网 IP 输入 192.168.200.0 ,子网掩码输入 255.255.255.0 点击 NAT 设置 , 输入网关 IP192.168.200.2( ip 地址必须是 192.168.200.2 ,不能是 192.168.200.1 这个 ip
有特殊用途 , 知道即可 ) ,点击确定
8.3 、设置虚拟机网路
虚拟机名称右键选择设置打开虚拟机设置。然后选择网络适配器 --> 选择自定义 (U) :特定虚拟网络 --> 确 定完成虚拟机网络设置8.4 、配置虚拟机 IP
vi /etc/sysconfig/network-scripts/ifcfg-ens33 删除其中的系统物理地址 HWADDR UUID
配置完成后保存文件
修改 /etc/sysconfig/network 来设置主机名称
重启系统 init 6
修改 /etc/hosts 文件,增加 DNS 支持
尝试使用 ping slave 命令测试连接状况
重新启动网卡: systemctl restart network
ping 百度的官网保证虚拟机能够访问外网,方便后期在线安装一些依赖软件
8.5 、安装 xshell xftp 工具。其中使用 xshell 工具可以很方便的操作 linux ,比如连接 linux 的命令行,通过xftp 文件文件传输工具可以向 linux 中上传文件
8.6 、双击 Xshell 快捷键运行 xshell
BOOTPROTO = static dhcp 修改为 static
使用 # 注释掉配置 UUID DEVICE
ONBOOT = yes 开机启动网卡
在文件末尾新增内容 :
IPADDR = 192.168.200.10
NETMASK = 255.255.255.0
GATEWAY = 192.168.200.2 # 和在配置虚拟网路中的网关保持一致
DNS1 = 8.8.8.8
DNS2 = 144.144.144.144
NETWORKING = yes
HOSTNAME = slave
192.168.1.3 master
192.168.1.4 slave
2 输入名称 basecentos (为每个虚拟机的连接起相应的名字)和将要连接的虚拟机 ip
点击用户身份验证,输入用户名 (root) 和密码 (root), 点击确定
第一次连接虚拟机时 xshell 需要保存连接用户的用户名和密码,下次登录时就可以不要在输入 , 方便后期登录。
需要使用 xftp 上传安装包,使用图形化界面拖拽即可完成上传处理 安装网络工具 net-tools linux 系同下的一个网络故障排查工具 , 工作中我们经常使用它查看集群网络运
行情况
安装 Linux
Linux 是一套免费使用和自由传播的类 Unix 操作系统,它主要用于基于 Intel x86 系列 CPU 的计算机上
Linux 是一个基于 POSIX UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统
Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统
Linux 目的是建立不受任何商品化软件的版权制约的、全世界都能自由使用的 Unix 兼容产品
尽管 Linux 拥有了 Unix 的全部功能和特点,但它却是最小、最稳定和最快速的操作系统。在最小配置下,它可以运行在仅4MB 的内存上
Linux 的组成
Linux 一般有四个主要部分:内核、 Shell 、文件结构和实用工具
Linux 内核是系统的心脏,是运行程序和管理像磁盘和打印机等硬件设备的核心程序
Shell 是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并它送入内核去执行
文件结构是文件存放在磁盘等存储设备上的组织方法
Linux 实用工具是专门的程序,用户也可以产生自己的工具
Linux 发行版的种类
Linux 发行版就是将 Linux 内核与应用软件做一个打包
Debian 分支,以 dpkg 进行软件包管理,文件后缀为 deb
Debian 运行起来极其稳定,这使得它非常适合用于服务器。并不适合新手用户,而是适合系统管
理员和高级用户。 Debian 支持如今的大多数架构(处理器)
Ubuntu Debian 的一款衍生版,也是当今最受欢迎的免费操作系统。 Ubuntu 侧重于它在这个市
场的应用,在服务器、云计算、甚至一些运行 Ubuntu 的移动设备上很常见。
RedHat 分支,以 rpm 进行软件包管理,文件后缀为 rpm Red Hat 这是第一款面向商业市场的 Linux 发行版。它有服务器版本,支持多处理器架构,包括 x86
x86_64 。红帽公司通过课程红帽认证系统管理员 RHCSA/ 红帽认证工程师 RHCE ,对系统管理员
进行培训和认证。就全球市场而言,总利润中 80% 来自支持,另外 20% 来自培训和认证
Centos 是一款企业级 Linux 发行版,它使用红帽企业级 Linux 中的免费源代码重新构建而成。这款
重构版完全去掉了注册商标以及 Binary 程序包方面一个非常细微的变化
其它分支
SuSE 是德国 SuSE Linux AG 公司发行维护的 Linux 发行版,是属于此公司的注册商标。第一个版本
出现在 1994 年年初。 2004 年这家公司被 Novell 公司收购
Gentoo 被认为是最佳学习对象,可以进而了解 Linux 操作系统的内部运作原理
虚拟机联网
VMware 提供的网络连接有 5 种,分别是桥接模式、 NAT 模式、仅主机模式、自定义和 LAN 区段。
桥接模式:虚拟机相当于一个独立主机,相当于虚拟机的网卡和宿主机的物理网卡均连接到虚拟机
软件所提供的 VMnet0 虚拟交换机上,因此虚拟机和宿主机是平等的,相当于一个网络中的两台计
算机。这种设置既可以保证虚拟机和宿主机通信,也可以和局域网内的其他主机通信,还可以连接
Internet ,是限制最少的连接方式,推荐新手使用。
网络地址转换 NAT 模式:虚拟机可访问主机和互联网,而其它主机无法访问虚拟机。相当于虚拟机
的网卡和宿主机的虚拟网卡 VMnet8 连接到虚拟机软件所提供的 VMnet8 虚拟交换机上,因此本机是
通过 VMnet8 虚拟网卡通信的。在这种网络结构中, VMware 为虚拟机提供了一个虚拟的 NAT 服务
器和一个虚拟的 DHCP 服务器,虚拟机利用这两个服务器可以连接到 Intemet 。所以,在正常情况
下,虚拟机系统只要设定自动获取 IP 地址,就能既和宿主机通信,又能连接到 Internet
仅主机模式:宿主机和虚拟机通信使用的是 VMware 的虚拟网卡 VMnet1 ,但是这种连接没有 NAT
服务器为虚拟机提供路由功能,所以仅主机网络只能连接宿主机,不能连接局域网,也不能连接
Internet 网络 自定义网络:可以手工选择使用哪块虚拟机网卡。如果选择 Vmnet1 ,就相当于桥接网络;如果选
VMnet8 ,就相当于 NAT 网络
LAN 区段:虚拟机之间组网,无法与宿主机或其它网络通信。这是新版 VMware 新增的功能,类似
于交换机中的 VLAN (虚拟局域网),可以在多台虚拟机中划分不同的虚拟网络
坑:如果虚拟机不能启动,并且报错和 BIOS 有关则根据电脑类型的不同,可以去百度查一下关于你电脑
BIOS 修改方式,开启虚拟机功能就可以了,保存之后重启,在点开虚拟机并启动
网络安全设置
因为 hadoop 需要使用很多端口,而且在 hadoop 在内网中使用,所以一般不需要防火墙设置
SSH 免密登录
SSH 是建立在应用层基础上的安全协议,是目前比较可靠,专为远程登录会话和其它网络服务提供安全
性的协议,可以有效的防止远程管理过程中的信息泄露问题。 SSH 是由客户端和服务端的软件组成,服
务端在后台运行并响应来自客户端的连接请求,客户端包含 ssh 程序以及像远程复制 scp 、完全文件传输
sftp 等应用程序。
Hadoop NameNode 需要通过 ssh 启动 slave 列表中各台主机的守护进程。
服务器 A 如果需要免密码登录到服务器 B 时,需要在服务器 A 上生成密钥对,将生成的公钥上传到 B 上,并
将公钥追加到 B authorized_keys 信任文件中。
cd /etc/sysconfig/network-scripts/
vi ./ifcfg-ens33
ONBOOT = yes
BOOTPROTO = static 静态 ip
IPADDR = 192 .168.109.7 ip 地址
NETMASK = 255 .255.255.0 子网掩码
GATEWAY = 192 .168.109.2 网关
DNS1 = 8 .8.8.8
DNS2 = 114 .114.114.114
- dd 整行删除
重启网络 service network restart
关闭防火墙
systemctl start firewalld.service # 启动防火墙
systemctl stop firewalld.service # 停止防火墙
systemctl status firewalld.service # 显示服务的状态
systemctl enable firewalld.service # 在开机时启用服务
systemctl disable firewalld.service # 在开机时禁用服务
Java 语言
程序 = 算法 + 数据结构
用户使用编程语言实现问题域到解域的映射,细节描述算法
汇编语言 -- 贴近于硬件设备
高级语言 --C# Java-- 贴近于自然语言 -- 需要编译过程将高级语言所编写的程序转换为计算机能够识 别的01
中级语言 --C
Java
一种编程语言、一种开发环境、一种应用环境、一种部署环境
ssh-keygen -t rsa 执行完成后则在 .ssh 文件夹下生成 pub 公钥文件
scp .ssh/id_rsa.pub root@B IP 地址 :~
关闭防火墙以及 SELinx
禁用 selinux
vi /etc/selinux/config
具体内容为
SELINUX=disabled
setenforce 0
getenforce
SELinux 被描述为在内核中执行的强制访问控制 MAC 安全结构。 SELinux 提供了一种强制执行某些安全 策略的方法,否则系统管理员无法有效实施这些策略。
什么是 Java 语言
一种面向对象的语言
一种平台无关的语言,必须程序运行的解释环境
一种健壮的语言,吸收了 C/C++ 语言的优点,但是去掉了影响程序健壮性的部分,例如指针、内存
的申请与释放等。
典型的应用场景:互联网环境
windows 下的安装
按照安装向导一步一步的执行,在选择安装内容时其中的公共 JRE 可装可不装,因为 JDK 中自带的就有 JRE,而公共 JRE 是脱离 JDK JRE
注意:在 JDK 的安装路径中不要出现中文、空格之类的特殊符号
配置 3 个参数(环境变量 --- 系统变量):
JAVA_HOME JDK 的安装路径,例如 C:\Java\jdk1.8.0_172
CLASSPATH :其中的值有 3 个,在 Windows 下使用分号进行分割,苏若在 Linux 下使用冒号做分割
. 表示当前目录
C:\Java\jdk1.8.0_172\lib\rt.jar
C:\Java\jdk1.8.0_172\lib\tools.jar
Path :注意是修改,不是创建,不要删除旧有配置,否则可能 windows 无法正常使用
在配置的末尾追加 ;C:\Java\jdk1.8.0_172\bin;
验证:在命令上运行命令
java -version 查看当前 jdk 的版本号
javac -version 查看当前 jdk 的版本号
Hello Java
1 、使用任意的文本编辑工具编写一个后缀为 .java 的文本文件
touch Hello.java
Java 是面向对象的编程语言,要求编写程序的开始就是定义类的开始
2 、编译程序为字节码文件【名称和源代码文件一致,只是后缀为 .class 的二进制文件】, JDK 中自带了
编译器 javac
javac Hello.java
如果有语法错误则编译失败,并进行告错
public class Hello { 其中 public class 是系统定义的关键字, Hello 是用户自定义的类名称,要求
必须和文件名称一致,包括大小写 ,{} 中用于用户自定义程序
public static void main ( String [] args ){ // 这个方法的名称不允许作任何调整,包括大小写 ,
这是程序的执行起始点
System . out . println ( "Hello Java!" ); Java 中语句以 ; 收尾, System . out . println
于实现在屏幕上输出字串内容,所谓的字串就是引号中所包含的字符序列
}
} 3 、使用解释器 java 解释执行字节码文件
java Hello[ 这里不是文件名称,是类名称,所以没有后缀 class]
如果使用文本编辑工具编写代码,问题在于没有任何提示,编码效率低;而且不停的需要进行切换【编辑发现问题-- 修改源代码】。所以需要使用 IDE 工具(集成开发环境),在工具中可以直接编写代码,编 译源程序并执行
Eclipse IBM 号称斥资 4000 万开发的通用开发平台,添加不同的插件就可以执行不同的工作, Eclipse
身就是使用 Java 开发的,所以进行 Java 开发时不用加任何插件。官方网站 eclipse.org
搭建开发环境
windows 下安装开发环境,部署在 Linux 系统上
JDK 安装
配置参数 JAVA_HOME CLASSPATH Path
验证 JDK 是否安装成功
Maven 安装
Maven Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型(缩写: POM )概念, Maven 利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。Maven 是一个项目管理工具,可对 Java 项目进行构建、依赖管理。 Maven 也可被用于构建和管理各种项目,例如 C# Ruby Scala 和 其他语言编写的项目。
使用 Maven 管理的 Java 项目都有相同的项目结构
使用 Maven 可以统一管理维护 jar
环境变量 MAVEN_HOME Path 路径
验证 maven 是否安装成功 mvn - v
Maven 提供了三种功能:
依赖的管理:仅仅通过 jar 包的几个属性,就能确定唯一的 jar 包,在指定的文件 pom.xml 中,只要
写入这些依赖属性,就会自动下载并管理 jar
项目的构建:内置很多的插件与生命周期,支持多种任务,比如校验、编译、测试、打包、部署、
发布 ...
项目的知识管理:管理项目相关的其他内容,比如开发者信息,版本等
Maven 概念模型
Maven 本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完 成,像编译是通过maven-compile-plugin 实现的、测试是通过 maven-surefire-plugin 实现的, maven 也内置了很多插件,所以我们在项目进行编译、测试、打包的过程是没有感觉到
进一步说,每个任务对应了一个插件目标 goal ,每个插件会有一个或者多个目标,例如 maven
compiler-plugin compile 目标用来编译位于 src/main/java/ 目录下的主源码, testCompile目标用来编        译位于src/test/java/目录下的测试源码。 多年来 Maven 社区积累了大量的经验,并随之形成了一个成熟的插件生态圈。 Maven 官方有两个插件列
表,第一个列表的 GroupId org.apache.maven.plugins ,这里的插件最为成熟,具体地址为: http://
maven.apache.org/plugins/index.html 。第二个列表的 GroupId org.codehaus.mojo ,这里的插件没
有那么核心,但也有不少十分有用,其地址为: http://mojo.codehaus.org/plugins.html
Maven 资源库
所谓的仓库就是用于存放项目需要的 jar 包的。 maven 采用一个仓库,多个项目的方式,让多个项目共享
一个仓库里的相同 jar 包。
Maven 的本地资源库是用来存储项目的依赖库,默认的文件夹是 .m2 目录,可能需要将其更改为另
一个文件夹
Maven 中央存储库是 Maven 用来下载所有项目的依赖库的默认位置
Maven 镜像存储库
maven 会默认从 maven 官方提供的服务器下载 jar 包。 而官方服务器在国外,因为大家都知道的原
因,网速很慢,而且容易卡断。 为了便于快速下载相关 jar 包,可以使用国内 maven 阿里云的下载
地址
Nexus 公司私服
私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供
局域网内的 Maven 用户使用
坐标
Maven 的世界中拥有数量非常巨大的构件,也就是我们平时用的一些 jar war 等文件。 Maven 定义了这
样一组规则:世界上任何一个构件都可以使用 Maven 坐标唯一标识。 Maven 坐标的元素包括 groupId
artifactId version packaging classifier
groupId :定义当前 Maven 项目隶属的实际项目。 groupId 的表示方式与 java 包名的表示方式类
似,通常与域名反向一一对应。
artifactId :该元素定义实际项目中的一个 Maven 项目 / 模块。
version :版本【可以分成稳定版本和快照版本】。
packaging :打包方式。如: jar war
classifier :不能直接定义,用来表示构件到底用于何种 jdk 版本。
常用的 Maven 命令
执行命令后,核心程序会从本地仓库寻找命令对应的插件,如果找不到,则会自动去网上下载资源到本
地仓库。然后通过插件去执行真正的操作。
mvn clean 清理
mvn compile 编译程序
mvn test-compile 编译测试程序
本地仓库配置 conf/setting.xml
<localRepository> d:/repo </localRepository>
修改默认中央仓库地址
<mirror>
<id> nexus-aliyun </id>
<mirrorOf> * </mirrorOf>
<name> aliyun </name>
<url> http://maven.aliyun.com/nexus/content/groups/public </url>
</mirror>
mvn test 执行测试
mvn package 打包
mvn install 安装到本地库
依赖的范围 scope
compile 默认 scope compile ,表示为当前依赖参与项目的编译、测试和运行阶段,属于强依赖。
打包之时,会达到包里去
test 依赖仅仅参与测试相关的内容,包括测试用例的编译和执行,比如定性的 Junit
runtime 依赖仅参与运行周期中的使用。一般这种类库都是接口与实现相分离的类库,比如 JDBC
库,在编译之时仅依赖相关的接口,在具体的运行之时,才需要具体的 mysql oracle 等等数据的
驱动程序。  此类的驱动都是为 runtime 的类库
provided 依赖在打包过程中,不需要打进去,这个由运行的环境来提供,比如 tomcat 或者基础类
库等等,事实上,该依赖可以参与编译、测试和运行等周期,与 compile 等同。区别在于打包阶段
进行了 exclude 操作
system 使用与 provided 相同,不同之处在于该依赖不从 maven 仓库中提取,而是从本地文件系统
中提取,其会参照 systemPath 的属性进行提取依赖
Maven 三套独立的生命周期
clean 真正构建前先执行清理操作
default 核心的构建部分,包括编译、测试、打包、安装、部署等
site 生成项目报告、站点、发布站点等
依赖冲突的解决方案
配置顺序优先
路径最短优先
使用 exclusion 进行排除设置
完整 settings.xml 文件
<dependency>
<groupid> org.hamcrest </groupid>
<artifactid> hamcrest-core </artifactid>
<version> 1.5 </version>
<scope> system </scope>
<systempath> ${basedir}/webapp/WEB-INF/lib/hamcrest.jar </systempath>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns = "http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd" >
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
<localRepository> D:\MyRepository </localRepository>
<!-- interactiveMode
| This will determine whether maven prompts you when it needs input. If
set to false,
| maven will use a sensible default value, perhaps based on some other
setting, for
| the parameter in question.
|
| Default: true
<interactiveMode>true</interactiveMode>
-->
<!-- offline
| Determines whether maven should attempt to connect to the network when
executing a build.
| This will have an effect on artifact downloads, artifact deployment,
and others.
|
| Default: false
<offline>false</offline>
-->
<!-- pluginGroups
| This is a list of additional group identifiers that will be searched
when resolving plugins by their prefix, i.e.
| when invoking a command line like "mvn prefix:goal". Maven will
automatically add the group identifiers
| "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not
already contained in the list.
|-->
<pluginGroups>
<!-- pluginGroup
| Specifies a further group identifier to use for plugin lookup.
<pluginGroup>com.your.plugins</pluginGroup>
-->
</pluginGroups>
<!-- proxies
| This is a list of proxies which can be used on this machine to connect
to the network.
| Unless otherwise specified (by system property or command-line
switch), the first proxy
| specification in this list marked as active will be used.
|-->
<proxies>
<!-- proxy
| Specification for one proxy, to be used in connecting to the
network.
|
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>proxyuser</username>
<password>proxypass</password>
<host>proxy.host.net</host>
<port>80</port>
<nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>
-->
</proxies>
<!-- servers
| This is a list of authentication profiles, keyed by the server-id used
within the system.
| Authentication profiles can be used whenever maven must make a
connection to a remote server.
|-->
<servers>
<!-- server
| Specifies the authentication information to use when connecting to a
particular server, identified by
| a unique name within the system (referred to by the 'id' attribute
below).
|
| NOTE: You should either specify username/password OR
privateKey/passphrase, since these pairings are
| used together.
|
<server>
<id>deploymentRepo</id>
<username>repouser</username>
<password>repopwd</password>
</server>
-->
<!-- Another sample, using keys to authenticate.
<server>
<id>siteServer</id>
<privateKey>/path/to/private/key</privateKey>
<passphrase>optional; leave empty if not used.</passphrase>
</server>
-->
</servers>
<!-- mirrors
| This is a list of mirrors to be used in downloading artifacts from
remote repositories.
|
| It works like this: a POM may declare a repository to use in resolving
certain artifacts.
| However, this repository may have problems with heavy traffic at
times, so people have mirrored
| it to several places.
|
| That repository definition will have a unique id, so we can create a
mirror reference for that
| repository, to be used as an alternate download site. The mirror site
will be the preferred
| server for that repository.
|-->
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given
repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of
this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique
across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<!-- 阿里云仓库 -->
<mirror>
<id> aliyunmaven </id>
<mirrorOf> * </mirrorOf>
<name> 阿里云公共仓库 </name>
<url> https://maven.aliyun.com/repository/public </url>
</mirror>
</mirrors>
<!-- profiles
| This is a list of profiles which can be activated in a variety of
ways, and which can modify
| the build process. Profiles provided in the settings.xml are intended
to provide local machine-
| specific paths and repository locations which allow the build to work
in the local environment.
|
| For example, if you have an integration testing plugin - like cactus -
that needs to know where
| your Tomcat instance is installed, you can provide a variable here
such that the variable is
| dereferenced during the build process to configure the cactus plugin.
|
| As noted above, profiles can be activated in a variety of ways. One
way - the activeProfiles
| section of this document (settings.xml) - will be discussed later.
Another way essentially
| relies on the detection of a system property, either matching a
particular value for the property,
| or merely testing its existence. Profiles can also be activated by JDK
version prefix, where a
| value of '1.4' might activate a profile when the build is executed on
a JDK version of '1.4.2_07'.
| Finally, the list of active profiles can be specified directly from
the command line.
|
| NOTE: For profiles defined in the settings.xml, you are restricted to
specifying only artifact
| repositories, plugin repositories, and free-form properties to
be used as configuration
| variables for plugins in the POM.
|
|-->
<profiles>
<!-- profile
| Specifies a set of introductions to the build process, to be
activated using one or more of the
| mechanisms described above. For inheritance purposes, and to
activate profiles via <activatedProfiles/>
| or the command line, profiles have to have an ID that is unique.
|
| An encouraged best practice for profile identification is to use a
consistent naming convention
| for profiles, such as 'env-dev', 'env-test', 'env-production',
'user-jdcasey', 'user-brett', etc.
| This will make it more intuitive to understand what the set of
introduced profiles is attempting
| to accomplish, particularly when you only have a list of profile
id's for debug.
|
| This profile example uses the JDK version to trigger activation, and
provides a JDK-specific repo.
<profile>
<id>jdk-1.4</id>
<activation>
<jdk>1.4</jdk>
</activation>
<repositories>
<repository>
<id>jdk14</id>
<name>Repository for JDK 1.4 builds</name>
<url>http://www.myhost.com/maven/jdk14</url>
<layout>default</layout>
<snapshotPolicy>always</snapshotPolicy>
</repository>
</repositories>
</profile>
-->
<profile>
<id> JDK-1.8 </id>
<activation>
<activeByDefault> true </activeByDefault>
<jdk> 1.8 </jdk>
</activation>
<properties>
<maven.compiler.source> 1.8 </maven.compiler.source>
<maven.compiler.target> 1.8 </maven.compiler.target>
<maven.compiler.compilerVersion> 1.8 </maven.compiler.compilerVersion>
</properties>
</profile>
<!--
| Here is another profile, activated by the system property 'target-
env' with a value of 'dev',
| which provides a specific path to the Tomcat instance. To use this,
your plugin configuration
| might hypothetically look like:
|
| ...
| <plugin>
| <groupId>org.myco.myplugins</groupId>
| <artifactId>myplugin</artifactId>
Linux 基础
通过远程工具登陆到 linux 后,所在的位置是当前登录用户的家目录 (home directory)
家目录的符号用 ~ 表示。
linux 的文件系统是一个树结构。
linux 文件系统的树根成为根目录,使用符号 "/" 表示。
linux 文件系统中使用符号 ".." 表示上级目录。
linux 文件系统中使用符号 "." 表示当前目录。
linux 文件系统中,如果文件使用 “.” 开头,就表示隐藏文件
linux 的路径表示方式有两种,一种是绝对路径 ( ”/“ 开头的路径 ) ,一种是相对路径
命令 cd(change directory) :跳转到其他目录
命令 ls :查看目录下包含什么东西
ls -l :显示详细信息
|
| <configuration>
| <tomcatLocation>${tomcatPath}</tomcatLocation>
| </configuration>
| </plugin>
| ...
|
| NOTE: If you just wanted to inject this configuration whenever
someone set 'target-env' to
| anything, you could just leave off the <value/> inside the
activation-property.
|
<profile>
<id>env-dev</id>
<activation>
<property>
<name>target-env</name>
<value>dev</value>
</property>
</activation>
<properties>
<tomcatPath>/path/to/tomcat/instance</tomcatPath>
</properties>
</profile>
-->
</profiles>
<!-- activeProfiles
| List of profiles that are active for all builds.
|
<activeProfiles>
<activeProfile>alwaysActiveProfile</activeProfile>
<activeProfile>anotherAlwaysActiveProfile</activeProfile>
</activeProfiles>
-->
</settings>
ls -a :显示隐藏文件
命令 pwd :显示当前所处位置的
命令 clear :清屏
命令 mkdir :创建文件夹
mkdir -p :递归创建上级文件夹
命令 touch :创建空白文件
命令 more :查看文件内容
命令 rm :删除文件
命令 rmdir :删除文件夹
命令 rm -rf: 删除文件 ( ) ,不论层级多深,一概删除,并且不给出提示
命令 cp(copy) :复制文件,还有一个功能是创建新文件
命令 mv(move): 移动文件,还有个功能是重命名
VI 操作:
当使用命令 vi f1 回车时,进入了 vi 编辑器内,处于只读状态 ( 只能看不能写 )
按字母 ”i“(insert) 或者 ”a“(append) 就可以进入编辑状态;
按键盘上的 ”Esc“ 键,再按 Shift+: ,进入命令状态
如果输入命令 wq ,意味着保存退出;
如果输入命令 q !,意味着不保存退出;
linux 的权限使用 9 位字符表示, rwx rwx rwx
这里面 r 表示读权限, w 表示写权限, x 表示执行权限, - 表示没有权限
9 位字符,每 3 位一组,分为 3
第一组表示创建者的权限
第二组表示创建者所在组的权限
第三组表示其他人的权限;
权限还可以使用数字表示。 rwx 用数字表示为 4+2+1=7
例如 chmod 777 f1
新创建文件的默认权限是 644 ;新创建文件夹的默认权限是 755.
命令 chmod :修改权限,三个组分别使用 u g o 表示,赋权限使用 “+” ,去掉权限使用 “-”
chmod u+x f1 // 表示文件 f1 的创建者增加执行权限
chmod o-r f1 // 表示文件 f1 的其他人去掉读权限
linux 领域内大多用在服务器上,很少遇到关机的操作。毕竟服务器上跑一个服务是永无止境的,除非
特殊情况下,不得已才会关机。
正确的关机流程为: sync > shutdown > reboot >poweroff 选项
功能
-h
-h=halt 关机
-r
-r=reboot 重启
基本语法
sync 功能描述:将数据由内存同步到硬盘中
poweroff 功能描述:关闭系统,等同于 shutdown -h now
reboot 功能描述:就是重启,等同于 shutdown -r now
shutdown [ 选项 ] 时间
经验技巧
Linux 系统中为了提高磁盘的读写效率,对磁盘采取了预读迟写操作方式。当用户保存文件时, Linux 核 心并不一定立即将保存数据写入物理磁盘中,而是将数据保存在缓冲区中,等缓冲区满时再写入磁盘, 这种方式可以极大的提高磁盘写入数据的效率。但是,也带来了安全隐患,如果数据还未写入磁盘时,系统掉电或者其他严重问题出现,则将导致数据丢失。使用sync 指令可以立即将缓冲区的数据写入磁盘
案例实操
1. 将数据由内存同步到硬盘中 sync
2. 重启 reboot
3. 关机 poweroff
4. 计算机将在 1 分钟后关机,并且会显示在登录用户的当前屏幕中
shutdown - h 1 ‘This server will shutdown after 1 mins’
5. 立马关机(等同于 halt shutdown - h now
6. 系统立马重启(等同于 reboot shutdown - r now
Maven 核心概念
Maven 之所以能够实现自动化的构建,和它的设计是紧密相关的。我们对 Maven 的学习就围绕它的九个 核心概念展开:
1) POM
Project Object Model :项目对象模型。将 Java 工程的相关信息封装为对象作为便于操作和管理的模 型。Maven 工程的核心配置。可以说学习 Maven 就是学习 pom.xml 文件中的配置。
POM 基础
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd" >
<!--1. 当前 pom 文件的版本不要动 -->
<modelVersion> 4.0.0 </modelVersion>
<!--2. 当前项目的坐标 , 当我们 install 时该项目在本地仓库的位置 --> 这是 project 的三个关键属性,被包裹在 <project ...> </project>
pom 当前文件版本
当前项目的坐标 gav: groupId artifactId version
当前项目所依赖的 jar
properties 标签
<project ...> </project> 下的 properties 自定义标签(类似设置变量)
<groupId> com.yan </groupId>
<artifactId> Hello </artifactId>
<version> 1.0-SNAPSHOT </version>
<dependencies>
<!--3. 当前项目所依赖的 jar 包的坐标 -->
<dependency>
<groupId> junit </groupId>
<artifactId> junit </artifactId>
<version> 4.0 </version>
<scope> test </scope>
</dependency>
</dependencies>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd" >
<modelVersion> 4.0.0 </modelVersion>
<groupId> org.example </groupId>
<artifactId> A </artifactId>
<version> 1.0-SNAPSHOT </version>
<properties>
<!-- 自定义标签 -->
<spring.version> 4.0.0.RELEASE </spring.version>
</properties>
<dependencies>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-context </artifactId>
<!-- 引用自定义标签:必须会因为后面的 hadoop 还会使用这种方式 -->
<version> ${spring.version} </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-webmvc </artifactId>
<version> ${spring.version} </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-jdbc </artifactId>
exclusions 标签
<dependency> <dependency> 下的 exclusions 将一个依赖排除
parent 标签指定父工程
父工程的存在是为多个子工程统一管理版本的:
<version> ${spring.version} </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-orm </artifactId>
<version> ${spring.version} </version>
</dependency>
</dependencies>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd" >
<modelVersion> 4.0.0 </modelVersion>
<groupId> org.example </groupId>
<artifactId> C </artifactId>
<version> 1.0-SNAPSHOT </version>
<dependencies>
<dependency>
<groupId> org.example </groupId>
<artifactId> B </artifactId>
<version> 1.0-SNAPSHOT </version>
<!-- junit 排除掉 -->
<exclusions>
<exclusion>
<groupId> junit </groupId>
<artifactId> junit </artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd" >
<modelVersion> 4.0.0 </modelVersion>
<!-- 父工程只是用来让子工程继承它的依赖。所以父工程中只需要有 pom.xml 即可 -->
<groupId> org.example </groupId>
<artifactId> Parent </artifactId>
子工程:
<version> 1.0-SNAPSHOT </version>
<!-- 父工程的打包方式只能为 pom 。打包方式有: pom jar war -->
<packaging> pom </packaging>
<!-- 如果在父工程中将依赖添加到 dependencyManagement 中,那么子工程需要指定继承父工
程中的哪个依赖,但不需要指定版本。子工程该依赖的版本会和父工程的版本保持一致。如果在父工程
中的依赖上不使用 dependencyManagement 该标签那么子工程会继承父工程中所有的依赖。 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-context </artifactId>
<version> 4.0.0.RELEASE </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-webmvc </artifactId>
<version> 4.0.0.RELEASE </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-jdbc </artifactId>
<version> 4.0.0.RELEASE </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-orm </artifactId>
<version> 4.0.0.RELEASE </version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd" >
<modelVersion> 4.0.0 </modelVersion>
<groupId> org.example </groupId>
<artifactId> Child </artifactId>
<version> 1.0-SNAPSHOT </version>
<!-- 指定父工程 -->
<parent>
<!-- 父工程的坐标 -->
<groupId> org.example </groupId>
<artifactId> Parent </artifactId>
<version> 1.0-SNAPSHOT </version>
<!-- 指定父工程 pom 文件的位置 -->
<relativePath> ../Parent/pom.xml </relativePath>
</parent>
</project>
20 modules 标签实现聚合
<project ...> </project> 下试用 modules 聚合
2) 约定的目录结构
现在 JavaEE 开发领域普遍认同一个观点:约定 > 配置 > 编码。意思就是能用配置解决的问题就不编码,能
基于约定的就不进行配置。而 Maven 正是因为指定了特定文件保存的目录才能够对我们的 Java 工程进行
自动化构建。
Maven 工程目录结构:
3) 坐标
[1] 在一个平面中使用 x y 两个向量可以唯一的确定平面中的一个点。
[2] 在空间中使用 x y z 三个向量可以唯一的确定空间中的一个点。
Maven 的坐标
使用如下三个向量在 Maven 的仓库中唯一的确定一个 Maven 工程。
[1] groupId :公司或组织的域名倒序 + 当前项目名称
[2] artifactId :当前项目的模块名称
[3] version :当前模块的版本
<!-- 聚合 -->
<modules>
<module> ../MakeFriend </module>
<module> ../OurFriends </module>
<module> ../HelloFriend </module>
<module> ../Hello </module>
</modules>
Hello
src
——main
————java
————resources
——test
————java
————resources
pom.xml
<groupId> com.yan.maven </groupId>
<artifactId> Hello </artifactId>
<version> 0.0.1-SNAPSHOT </version> 如何通过坐标到仓库中查找 jar 包?
[1] gav 三个向量连起来
com.yan.maven+Hello+0.0.1 - SNAPSHOT
[2] 以连起来的字符串作为目录结构到仓库中查找
com/yan/maven/Hello/0.0.1 - SNAPSHOT/Hello - 0.0.1 - SNAPSHOT.jar
※ 注意:自己的 Maven 工程必须执行安装操作才会进入仓库。安装的命令是: mvn install
4) 依赖管理
1) 基本概念
A jar 包需要用到 B jar 包中的类时,就说 A B 有依赖。例如: commons-fileupload-1.3.jar 依赖于
commons-io-2.0.1.jar
通过第二个 Maven 工程我们已经看到,当前工程会到本地仓库中根据坐标查找它所依赖的 jar 包。
配置的基本形式是使用 dependency 标签指定目标 jar 包的坐标。例如:
2) 直接依赖和间接依赖
如果 A 依赖 B B 依赖 C ,那么 A B B C 都是直接依赖,而 A C 是间接依赖。
2.1) 基本概念 当A jar 包需要用到 B jar 包中的类时,我们就说 A B 有依赖。例如: commons-fileupload-1.3.jar 依赖于 commons-io-2.0.1.jar。
通过第二个 Maven 工程我们已经看到,当前工程会到本地仓库中根据坐标查找它所依赖的 jar 包。
配置的基本形式是使用 dependency 标签指定目标 jar 包的坐标。例如:
2.2) 直接依赖和间接依赖
如果 A 依赖 B B 依赖 C ` 那么 A B B C 都是直接依赖,而 A C 是间接依赖。
<dependency>
<!-- 坐标 -->
<groupId> junit </groupId>
<artifactId> junit </artifactId>
<version> 4.0 </version>
<!-- 依赖的范围 -->
<scope> test </scope>
</dependency>
<dependency>
<!-- 坐标 -->
<groupId> junit </groupId>
<artifactId> junit </artifactId>
<version> 4.0 </version>
<!-- 依赖的范围 -->
<scope> test </scope>
</dependency>
8 依赖的范围
1) compile default
main 目录下的 Java 代码可以访问这个范围的依赖
test 目录下的 Java 代码可以访问这个范围的依赖
部署到 Tomcat 服务器上运行时要放在 WEB-INF lib 目录下
例如:对 Hello 的依赖。主程序、测试程序和服务器运行时都需要用到。
2) test
main 目录下的 Java 代码不能访问这个范围的依赖
test 目录下的 Java 代码可以访问这个范围的依赖
部署到 Tomcat 服务器上运行时不会放在 WEB-INF lib 目录下
例如:对 junit 的依赖。仅仅是测试程序部分需要。
3) provided
main 目录下的 Java 代码可以访问这个范围的依赖
test 目录下的 Java 代码可以访问这个范围的依赖
部署到 Tomcat 服务器上运行时不会放在 WEB-INF lib 目录下
例如: servlet-api 在服务器上运行时, Servlet 容器会提供相关 API ,所以部署的时候不需要。(适用:有
些功能模块现阶段临时使用,但是不准备部署到服务器中)
4) 其他: runtime import system 等。
各个依赖范围的作用可以概括为下图:
依赖的传递性
当存在间接依赖的情况时,主工程对间接依赖的 jar 可以访问吗?这要看间接依赖的 jar 包引入时的依赖范
—— 只有依赖范围为 compile 时可以访问。例如: 依赖的原则:解决 jar 包冲突
1) 路径最短者优先
2) 路径相同时先声明者优先
这里 声明 的先后顺序指的是 dependency 标签配置的先后顺序。
依赖的排除
1) 有的时候为了确保程序正确,可以将有可能重复的间接依赖排除。请看如下的例子:
假设当前工程为 MakeFriend ,直接依赖 OurFriends OurFriends 依赖 commons-logging 1.1.1 对于
MakeFriend 来说是间接依赖( MakeFriend -|> OurFriends -|> commons-logging 1.1.1 )。
当前工程 MakeFriend 直接依赖 commons-logging 1.1.2 ,这样会出现 commons-logging 的版本冲
突,具体表现是有可能找不到对应的类。
加入 exclusions 配置后可以在依赖 OurFriends 的时候排除版本为 1.1.1 commons-logging 的间 接依赖
<dependency>
<groupId> com.yan.maven </groupId>
<artifactId> OurFriends </artifactId>
<version> 1.0-SNAPSHOT </version>
<!-- 依赖排除 -->
<exclusions>
<exclusion>
<groupId> commons-logging </groupId>
<artifactId> commons-logging </artifactId>
</exclusion>
<!-- 或者用 * 号排除组内所有 >
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>*</artifactId>
</exclusion>
<-->
</exclusions>
</dependency>
<dependency>
<groupId> commons-logging </groupId>
<artifactId> commons-logging </artifactId>
<version> 1.1.2 </version>
其中每种打包方式都可以排除依赖,以便正确打包到服务器上执行项目。
统一管理目标 jar 包的版本
以对 Spring jar 包依赖为例: Spring 的每一个版本中都包含 spring-context springmvc jar 包。我们
应该导入版本一致的 Spring jar 包,而不是使用 4.0.0 spring-context 的同时使用 4.1.1 springmvc
问题是如果我们想要将这些 jar 包的版本统一升级为 4.1.1 ,是不是要手动一个个修改呢?显然,我们有统
一配置的方式:
</dependency>
24
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-context </artifactId>
<version> 4.0.0.RELEASE </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-webmvc </artifactId>
<version> 4.0.0.RELEASE </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-jdbc </artifactId>
<version> 4.0.0.RELEASE </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-orm </artifactId>
<version> 4.0.0.RELEASE </version>
</dependency>
<!-- 统一管理当前模块的 jar 包的版本 -->
<properties>
<spring.version> 4.0.0.RELEASE </spring.version>
</properties>
...
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-context </artifactId>
<version> ${spring.version} </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-webmvc </artifactId>
<version> ${spring.version} </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-jdbc </artifactId>
<version> ${spring.version} </version>
</dependency>
<dependency>
<groupId> org.springframework </groupId>
<artifactId> spring-orm </artifactId>
这样一来,进行版本调整的时候只改一改地方就行了。
5) 仓库管理
1) 分类
本地仓库:为当前本机电脑上的所有 Maven 工程服务。
远程仓库
[1] 私服:架设在当前局域网环境下,为当前局域网范围内的所有 Maven 工程服务。
[2] 中央仓库:架设在 Internet 上,为全世界所有 Maven 工程服务。
[3] 中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响
应用户请求。
1) 仓库中的文件
Maven 的插件
我们自己开发的项目的模块
第三方框架或工具的 jar
※不管是什么样的 jar 包,在仓库中都是按照坐标生成目录结构,所以可以通过统一的方式查
询或依赖。
6) 生命周期
1) 什么是 Maven 的生命周期?
Maven 生命周期定义了各个构建环节的执行顺序,有了这个清单, Maven 就可以自动化的执行构建命令 
Maven 有三套相互独立的生命周期,分别是:
Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
Default Lifecycle 构建的核心部分,编译,测试,打包,安装,部署等等。
Site Lifecycle 生成项目报告,站点,发布站点。
再次强调一下它们是相互独立的,你可以仅仅调用 clean 来清理工作目录,仅仅调用 site 来生成站点。当 然你也可以直接运行mvn clean install site 运行所有这三套生命周期。
<version> ${spring.version} </version>
</dependency>
每套生命周期都由一组阶段 (Phase) 组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean ,这个 clean Clean 生命周期的一个阶段。有 Clean 生命周期,也有 clean 阶段。
2) clean 生命周期
Clean 生命周期一共包含了三个阶段:
pre-clean 执行一些需要在 clean 之前完成的工作
clean 移除所有上一次构建生成的文件
post-clean 执行一些需要在 clean 之后立刻完成的工作
3) Site 生命周期
pre-site 执行一些需要在生成站点文档之前完成的工作
site 生成项目的站点文档
post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
site-deploy 将生成的站点文档部署到特定的服务器上
这里经常用到的是 site 阶段和 site-deploy 阶段,用以生成和发布 Maven 站点,这可是 Maven 相当强大的功能,Manager 比较喜欢,文档及统计数据自动生成,很好看。
4) Default 生命周期
Default 生命周期是 Maven 生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。这里,只解释一些比较重要和常用的阶段:
validate
generate-sources
process-sources
generate-resources
process-resources 复制并处理资源文件,至目标目录,准备打包。
compile 编译项目的源代码。
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources 复制并处理资源文件,至目标测试目录。
test-compile 编译测试源代码。
process-test-classes
test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
prepare-package
package 接受编译好的代码,打包成可发布的格式,如 JAR
pre-integration-test integration-test
post-integration-test
verify
install 将包安装至本地仓库,以让其它项目依赖。
deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行。
p.s. 加粗的为要掌握的生命周期
5) 生命周期与自动化构建
运行任何一个阶段的时候,它前面的所有阶段都会被运行,例如我们运行 mvn install 的时候,代码 会被编译,测试,打包。这就是Maven 为什么能够自动执行构建过程的各个环节的原因。此外, Maven 的插件机制是完全依赖Maven 的生命周期的,因此理解生命周期至关重要。
运行 maven 命令
打开 cmd 命令行,进入 Hello 项目根目录 (pom.xml 文件所在目录 ) 执行 mvn compile 命令,查看根目录化
cmd 中继续录入 mvn clean 命令,然后再次查看根目录变化
cmd 中录入 mvn compile 命令 , 查看根目录变化
cmd 中录入 mvn test-compile 命令, 查看 target 目录的变化
cmd 中录入 mvn test 命令,查看 target 目录变化
cmd 中录入 mvn package 命令 , 查看 target 目录变化
cmd 中录入 mvn install 命令, 查看本地仓库的目录变化
7) 插件和目标
1) Maven 的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。
2) 每个插件都能实现多个功能,每个功能就是一个插件目标。
3) Maven 的生命周期与插件目标相互绑定,以完成某个具体的构建任务。
例如: compile 就是插件 maven-compiler-plugin 的一个功能; pre-clean 是插件 maven-clean-plugin 的 一个目标。
Maven 本身的打包插件不负责将依赖的 jar 包一并打入到 jar 包中。如果项目所依赖的 jar 包在服务器环境中提供了还好,如果服务器环境中没有提供,则比较悲惨,运行各种ClassNotFound…. 因此需要一款能够将项目所依赖的jar 包 一并打入到 jar 中的插件来解决这些问题。
<build>
<plugins>
<plugin>
<artifactId> maven-assembly-plugin </artifactId>
<configuration>
<descriptorRefs>
<descriptorRef> jar-with-dependencies </descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<!-- 指定主类 -->
<mainClass> xxx.xxx.XXX </mainClass>
</manifest>
项目名称
对应配置
Hello
<dependency> <groupId>junit</groupId>
<artifactId>junit</artifactId> <version>4.0</version>
<scope>test</scope> </dependency>
HelloFriend
<dependency> <groupId>junit</groupId>
<artifactId>junit</artifactId> <version>4.0</version>
<scope>test</scope> </dependency>
MakeFriend
<dependency> <groupId>junit</groupId>
<artifactId>junit</artifactId> <version>4.0</version>
<scope>test</scope> </dependency>
打包和聚合的区别
Maven 打包更适用于把很多 Jar 包打包成一个 jar 包;
聚合是逻辑上把多个 Model 当成同一个 Project 共同 clean/install... 等操作。
8) 继承
由于非 compile 范围的依赖信息是不能在 依赖链 中传递的,所以有需要的工程只能单独配置。例如:
此时如果项目需要将各个模块的 junit 版本统一为 4.9 ,那么到各个工程中手动修改无疑是非常不可取的。
使用继承机制就可以将这样的依赖信息统一提取到父工程模块中进行统一管理。
创建父工程
父工程的打包方式只能为 pom
父工程只需要保留 pom.xml 文件即可
注意:打包的方式有多种: jar war pom
</archive>
</configuration>
<executions>
<execution>
<id> make-assembly </id>
<phase> package </phase>
<goals>
<goal> single </goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<groupId> com.yan.maven </groupId>
<artifactId> Parent </artifactId>
<packaging> pom </packaging>
<version> 1.0-SNAPSHOT </version>
在子工程中引用父工程
父工程坐标
继承配置
此时如果子工程的 groupId version 如果和父工程重复则可以删除。
在父工程中管理依赖
Parent 项目中的 dependencies 标签,用 dependencyManagement 标签括起来(推荐)。如果
Parent 项目不使用 dependencies 标签,子项目会继承所有的依赖(不推荐)。
在子项目中重新指定需要的依赖,删除范围和版本号
父工程的存在目的是为了统一子工程依赖版本的一致。
9) 聚合
将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进
clean 操作。而使用了聚合之后就可以批量进行 Maven 工程的安装、清理工作。
<parent>
<groupId> ... </groupId>
<artifactId> ... </artifactId>
<version> ... </version>
<!-- 指定从当前 pom.xml 文件出发寻找父工程的 pom.xml 文件的相对路径 -->
<relativePath> .. </relativePath>
</parent>
<parent>
<groupId> com.yan.maven </groupId>
<artifactId> Parent </artifactId>
<version> 1.0-SNAPSHOT </version>
<!-- 指定从当前 pom.xml 文件出发寻找父工程的 pom.xml 文件的相对路径 -->
<relativePath> ../Parent/pom.xml </relativePath>
</parent>
<!-- 依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId> junit </groupId>
<artifactId> junit </artifactId>
<version> 4.0 </version>
<scope> test </scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId> junit </groupId>
<artifactId> junit </artifactId>
</dependency>
配置聚合
在总的聚合工程中使用 modules/module 标签组合,指定模块工程的相对路径即可
Maven 可以根据各个模块的继承和依赖关系自动选择安装的顺序
<!-- 聚合 -->
<modules>
<module> ../MakeFriend </module>
<module> ../OurFriends </module>
<module> ../HelloFriend </module>
<module> ../Hello </module>
</modules>
;