Hadoop Yarn (3) 应用运行原理

3. YARN应用运行原理(重点)

yarn架构图

3.1 YARN应用提交过程

  • Application在Yarn中的执行过程,整个执行过程可以总结为三步:

    • 应用程序提交
    • 启动应用的ApplicationMaster实例
    • ApplicationMaster 实例管理应用程序的执行
  • 具体提交过程为:

    • 客户端程序向 ResourceManager 提交应用,并请求一个 ApplicationMaster 实例;
    • ResourceManager 找到一个可以运行一个 Container 的 NodeManager,并在这个 Container 中启动 ApplicationMaster 实例;
    • ApplicationMaster 向 ResourceManager 进行==注册==,注册之后客户端就可以查询 ResourceManager 获得自己 ApplicationMaster 的详细信息,以后就可以和自己的 ApplicationMaster 直接交互了(这个时候,客户端主动和 ApplicationMaster 交流,应用先向 ApplicationMaster 发送一个满足自己需求的资源请求);
    • ApplicationMaster 根据 resource-request协议 向 ResourceManager 发送 resource-request请求;
    • 当 Container 被成功分配后,ApplicationMaster 通过向 NodeManager 发送 container-launch-specification信息来启动Container,container-launch-specification信息包含了能够让Container 和 ApplicationMaster 交流所需要的资料;
    • 应用程序的代码以 task 形式在启动的 Container 中运行,并把运行的进度、状态等信息通过 application-specific协议 发送给ApplicationMaster;
    • 在应用程序运行期间,提交应用的客户端主动和 ApplicationMaster 交流获得应用的运行状态、进度更新等信息,交流协议也是 application-specific协议;
    • 应用程序执行完成并且所有相关工作也已经完成,ApplicationMaster 向 ResourceManager==取消注册==然后关闭,用到所有的 Container 也归还给系统。
  • 精简版的:

    • 步骤1:用户将应用程序提交到 ResourceManager 上;
    • 步骤2:ResourceManager为应用程序 ApplicationMaster 申请资源,并与某个 NodeManager 通信启动第一个 Container,以启动ApplicationMaster;
    • 步骤3:ApplicationMaster 与 ResourceManager 注册进行通信,为内部要执行的任务申请资源,一旦得到资源后,将于 NodeManager 通信,以启动对应的 Task;
    • 步骤4:所有任务运行完成后,ApplicationMaster 向 ResourceManager 注销,整个应用程序运行结束。

3.2 MapReduce on YARN

img

  • 提交作业

    • ①程序打成jar包,在客户端运行hadoop jar命令,提交job到集群运行
    • job.waitForCompletion(true)中调用Job的submit(),此方法中调用JobSubmitter的submitJobInternal()方法;
    • ②submitClient.getNewJobID()向resourcemanager请求一个MR作业id
    • 检查输出目录:如果没有指定输出目录或者目录已经存在,则报错
    • 计算作业分片;若无法计算分片,也会报错
    • ③运行作业的相关资源,如作业的jar包、配置文件、输入分片,被上传到HDFS上一个以作业ID命名的目录(jar包副本默认为10,运行作业的任务,如map任务、reduce任务时,可从这10个副本读取jar包)
    • ④调用resourcemanager的submitApplication()提交作业
    • 客户端每秒查询一下作业的进度(map 50% reduce 0%),进度如有变化,则在控制台打印进度报告;
    • 作业如果成功执行完成,则打印相关的计数器
    • 但如果失败,在控制台打印导致作业失败的原因(要学会查看日志,定位问题,分析问题,解决问题)
  • 初始化作业

    • 当ResourceManager(一下简称RM)收到了submitApplication()方法的调用通知后,请求传递给RM的scheduler(调度器);调度器分配container(容器)
    • ⑤a RM与指定的NodeManager通信,通知NodeManager启动容器;NodeManager收到通知后,创建占据特定资源的container;
    • ⑤b 然后在container中运行MRAppMaster进程
    • ⑥MRAppMaster需要接受任务(各map任务、reduce任务的)的进度、完成报告,所以appMaster需要创建多个簿记对象,记录这些信息
    • ⑦从HDFS获得client计算出的输入分片split
    • 每个分片split创建一个map任务
    • 通过 mapreduce.job.reduces 属性值(编程时,jog.setNumReduceTasks()指定),知道当前MR要创建多少个reduce任务
    • 每个任务(map、reduce)有task id
  • Task 任务分配

    • 如果小作业,appMaster会以==uberized==的方式运行此MR作业;appMaster会决定在它的JVM中顺序执行此MR的任务;

    • 原因是,若每个任务运行在一个单独的JVM时,都需要单独启动JVM,分配资源(内存、CPU),需要时间;多个JVM中的任务再在各自的JVM中并行运行

    • 若将所有任务在appMaster的JVM中==顺序执行==的话,更高效,那么appMaster就会这么做 ,任务作为uber任务运行

    • 小作业判断依据:①小于10个map任务;②只有一个reduce任务;③MR输入大小小于一个HDFS块大小

    • 如何开启uber?设置属性 mapreduce.job.ubertask.enable 值为true

      configuration.set("mapreduce.job.ubertask.enable", "true");
    • 在运行任何task之前,appMaster调用setupJob()方法,创建OutputCommitter,创建作业的最终输出目录(一般为HDFS上的目录)及任务输出的临时目录(如map任务的中间结果输出目录)

    • ⑧若作业不以uber任务方式运行,那么appMaster会为作业中的每一个任务(map任务、reduce任务)向RM请求container

    • 由于reduce任务在进入排序阶段之前,所有的map任务必须执行完成;所以,为map任务申请容器要优先于为reduce任务申请容器

    • 5%的map任务执行完成后,才开始为reduce任务申请容器

    • 为map任务申请容器时,遵循==数据本地化==,调度器尽量将容器调度在map任务的输入分片所在的节点上(==移动计算,不移动数据==)

    • reduce任务能在集群任意计算节点运行

    • 默认情况下,为每个map任务、reduce任务分配1G内存、1个虚拟内核,由属性决定mapreduce.map.memory.mb、mapreduce.reduce.memory.mb、mapreduce.map.cpu.vcores、mapreduce.reduce.reduce.cpu.vcores

  • Task 任务执行

    • 当调度器为当前任务分配了一个NodeManager(暂且称之为NM01)的容器,并将此信息传递给appMaster后;appMaster与NM01通信,告知NM01启动一个容器,并此容器占据特定的资源量(内存、CPU)
    • NM01收到消息后,启动容器,此容器占据指定的资源量
    • 容器中运行YarnChild,由YarnChild运行当前任务(map、reduce)
    • ⑩在容器中运行任务之前,先将运行任务需要的资源拉取到本地,如作业的JAR文件、配置文件、分布式缓存中的文件
  • 作业运行进度与状态更新

    • 作业job以及它的每个task都有状态(running、successfully completed、failed),当前任务的运行进度、作业计数器
    • 任务在运行期间,每隔==3秒==向appMaster汇报执行进度、状态(包括计数器)
    • appMaster汇总目前运行的所有任务的上报的结果
    • 客户端每隔1秒,轮询访问appMaster获得作业执行的最新状态,若有改变,则在控制台打印出来
  • 完成作业

    • appMaster收到最后一个任务完成的报告后,将作业状态设置为成功
    • 客户端轮询appMaster查询进度时,发现作业执行成功,程序从waitForCompletion()退出
    • 作业的所有统计信息打印在控制台
    • appMaster及运行任务的容器,清理中间的输出结果,释放资源
    • 作业信息被历史服务器保存,留待以后用户查询

3.3 YARN应用生命周期

  • RM: Resource Manager
  • AM: Application Master
  • NM: Node Manager
  1. Client向RM提交应用,包括AM程序及启动AM的命令。
  2. RM为AM分配第一个容器,并与对应的NM通信,令其在容器上启动应用的AM。
  3. AM启动时向RM注册,允许Client向RM获取AM信息然后直接和AM通信。
  4. AM通过资源请求协议,为应用协商容器资源。
  5. 如容器分配成功,AM要求NM在容器中启动应用,应用启动后可以和AM独立通信。
  6. 应用程序在容器中执行,并向AM汇报。
  7. 在应用执行期间,Client和AM通信获取应用状态。
  8. 应用执行完成,AM向RM注销并关闭,释放资源。

    申请资源->启动appMaster->申请运行任务的container->分发Task->运行Task->Task结束->回收container

Views: 45

Java带Jar包编译方式

java命令行编译带jar包

项目的结构如下

src
  │--   A.java
  │
  ├─pkg
  │     B.java
  │
  └─lib1
  │     ext1.jar
  └─lib2
  │     ext2.jar
  └─jars
        jar1.jar
        jar2.jar
        jar3.jar

简单的不带包名的java源文件编译

编译

$ cd src
$ javac -encoding utf8 A.java

运行

$ java A

简单的带包名的java源文件编译

编译

$ cd src
$ javac -encoding utf8 pkg/B.java

运行

$java pkg.B

对带一个jar包的java源文件编译

编译

$ cd src
$ javac pkg/B.java -cp lib1/ext1.jar

运行

$ java -cp .:lib1/ext1.jar pkg.B

注意

  • 其中 -cp 等同于 --classpath
  • 路径分隔符要注意windows系统要把冒号改成分号

引入多个jar包的java源文件编译

编译

$ javac -Djava.ext.dirs=./jars   -encoding utf8 A.java

运行

$ java -Djava.ext.dirs=./jars A

另外:对于多个jar分散在多个文件夹中时,
编译使用:

javac -Djava.ext.dirs=./lib1:./lib2:./jars A.java

运行时使用:

java -Djava.ext.dirs=./lib1:./lib2:./jars A

Views: 29

电商日志分析项目 – 02 日志的生成和采集(Flume)

Hadoop安装与配置

Hadoop3.1.4的单机安装参考

Flume的安装与配置

Flume的安装与配置参考

Apache httpd 安装

安装httpd的原因主要是使用它提供的ab压测工具.

  1. 安装httpd
yum install -y httpd
  1. 配置httpd,为了避免和ngixn端口冲突修改端口号为81,配置如下:
vi /etc/httpd/conf/httpd.conf

修改内容如下:

#Listen 80
Listen 81
  1. 启动服务
systemctl enable httpd # 开机自启动
systemctl start httpd # 启动httpd
  1. 查看启动状态
systemctl status httpd

注意:

  • 其实使用httpd只是为了使用ab工具,无需启动httpd服务

AB压测生成日志

访问http://hadoop100/university/ 登陆进入后台界面

后台UI界面生成商品链接

点击获取商品链接,页面打印生成的JSON格式数据
file

同时在服务器生成文件/tmp/project-urls.txt,里面保存着所有商品链接:

http://hadoop100/shop/detail.html?id=4028f00176e118120176e17d0e0f0000
http://hadoop100/shop/detail.html?id=4028f00176e1aa620176e2319b730000
http://hadoop100/shop/detail.html?id=4028f00176e1aa620176e6a991e60001
http://hadoop100/shop/detail.html?id=4028f00176e1aa620176e6ab478d0002
http://hadoop100/shop/detail.html?id=4028f00176e1aa620176e6aca6890003
http://hadoop100/shop/detail.html?id=4028f08176e0e2af0176e0e2bd600007

后台UI界面AB压测生成日志

编写压测脚本ab_test.sh,内容可自行修改,如下:

$ vi /opt/bin/project/ab-test.sh

#!/bin/bash
n=$(cat /tmp/project-urls.txt | wc -l)

for ((i=1;i<=$n;i++))
do
    echo "No.$i"
    url=$(shuf -n1 /tmp/project-urls.txt)
    r=$(shuf -i 6-100 -n 1)
    c=$(shuf -i 1-5 -n 1)

    echo "access url  -> $url"
    echo "requests    -> $r"
    echo "concurrency -> $c"

    ab -n $r -c $c $url >> /tmp/project-abtest-results.log &
done

说明:

  • 给与执行权限方便执行
  • shuf在指定范围生成随机数
  • ab apache benchmark工具,常用于压力测试
    • -n 请求数
    • -c 并发数
  • 压测结果可在/tmp/project-abtest-resuilts.log中找到

压测结果说明
file

点击AB压测生成日志
file

产生的日志在/var/log/nginx/access.log中。

使用FLume收集滚动日志上传到HDFS上

修改nginx生成的日志文件所有者

nginx默认生成的日志文件access.log的用户组和用户分别是adm和nginx,如下所示:

[hadoop@hadoop100 nginx]$ ll
-rw-r-----  1 nginx  adm    135470 Apr 21 01:22 access.log

而现在需要让另一用户读取该文件,做日志的分析监控. 应该修改日志文件的所属用户组和用户,避免出现权限问题。

修改Nginx运行时进程的用户与组

Nginx运行时进程需要有用户与组的支持,用以实现对网站文件读取时进行访问控制。主进程由 root创建,子进程由指定的用户与组创建, 一般默认为 nginx admnobody nobody

由于我们项目中使用的操作账户为hadoop,而这个用户对nginx用户生成的日志没有操作权限,因此使用Flume收集时会出现权限问题导致收集失败。

当然也可以简单粗暴的临时使用下面的命令解决问题

$ sudo chown hadoop:hadoop -R /var/log/nginx/

但是这样并不能从根本解决问题,因为下次滚动生成的日志所有者还会变成原来配置的。

修改 nginx 用户与组有两种办法。如果是编译安装,可以在编译前指定用户和组;也可以修改配置文件指定用户与组,然后重启服务器即可。

编译 nginx 时指定用户与组

即修改 ./configure 后面指定用户与组的参数

./configure \
--prefix=/usr/local/nginx \
--user=nginx \        //指定用户名是 nginx
--group=nginx \       //指定组名是 nginx
--with-http_stub_status_module

修改 nginx 配置文件指定用户与组

打开文件/etc/nginx/nginx.conf,我这里默认是

user nginx;   //修改用户为nginx,组为nginx

现在我们改成

user hadoop hadoop; // //修改用户为 hadoop,组为 hadoop

sudo service nginx restart重启服务后,查看进程情况,主进程由root创建,子进程则由nginx创建。

file

修改 Nginx 日志滚动策略

可以通过修改这个文件修改 Nginx 的日志滚动策略(如有需要)

$ sudo vi /etc/logrotate.d/nginx

/var/log/nginx/*.log {
        daily
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 nginx adm
        sharedscripts
        postrotate
                if [ -f /var/run/nginx.pid ]; then
                        kill -USR1 $(cat /var/run/nginx.pid)
                fi
        endscript
}

其中nginx adm就是滚动日志的权限拥有者及所在群组, 640表示滚动日志的权限。下面比如我们需要将滚动日志的用户组和用户改为hadoop:hadoop, 只需要修改此处:

#create 640 nginx adm
create 640 hadoop hadoop

滚动access.log日志文件

接着编写Linux Shell脚本实现/var/log/nginx/access.log日志滚动到flume-logs目录下。

/opt/bin/project目录下新建rolling-log.sh,并添加执行权限,内容如下:

#!/bin/bash
#定义日期格式
dataformat=$(date +%Y-%m-%d-%H-%M-%S)

#复制access.log并重命名,添加时间信息
cp /var/log/nginx/access.log /var/log/nginx/access_$dataformat.log

host=$(hostname)
sed -i 's/^/'${host}',&/g' /var/log/nginx/access_$dataformat.log
#统计日志文件行数
lines=$(wc -l < /var/log/nginx/access_$dataformat.log)

#将格式化的日志移动到flumeLogs目录下
mv /var/log/nginx/access_$dataformat.log /var/log/nginx/flume-logs

#清空access.log的内容
sed -i '1,'${lines}'d' /var/log/nginx/access.log

#重启nginx , 使access.log可以继续滚动
kill -USR1 $(cat /var/run/nginx.pid)

##返回给服务器信息
ls -al /var/log/nginx/flume-logs/

后台管理界面点击生成滚动日志

file

编写Flume Agent配置文件:

vi /opt/pkg/flume/conf/log2hdfs.conf`

# define the agent a1
a1.sources=r1
a1.channels=c1
a1.sinks=k1

# define the source
#上传目录类型
a1.sources.r1.type=spooldir
a1.sources.r1.spoolDir=/var/log/nginx/flume-logs
#定义自滚动日志完成后的后缀名
a1.sources.r1.fileSuffix=.FINISHED
#根据每行文本内容的大小自定义最大长度4096=4k
a1.sources.r1.deserializer.maxLineLength=4096

# define the sink
a1.sinks.k1.type = hdfs
#上传的文件保存在hdfs的/flume/logs目录下
a1.sinks.k1.hdfs.path = hdfs://hadoop100:8020/flume/logs/%y-%m-%d/
a1.sinks.k1.hdfs.filePrefix=access_log
a1.sinks.k1.hdfs.fileSufix=.log
a1.sinks.k1.hdfs.batchSize=1000
a1.sinks.k1.hdfs.fileType = DataStream
a1.sinks.k1.hdfs.writeFormat= Text
# roll 滚动规则:按照数据块128M大小来控制文件的写入,与滚动相关其他的都设置成0
#为了演示,这里设置成500k写入一次
a1.sinks.k1.hdfs.rollSize= 512000
a1.sinks.k1.hdfs.rollCount=0
a1.sinks.k1.hdfs.rollInteval=0
#控制生成目录的规则:一般是一天或者一周或者一个月一次,这里为了演示设置10秒
a1.sinks.k1.hdfs.round=true
a1.sinks.k1.hdfs.roundValue=10
a1.sinks.k1.hdfs.roundUnit= second
#是否使用本地时间
a1.sinks.k1.hdfs.useLocalTimeStamp=true

#define the channel
a1.channels.c1.type = memory
#自定义event的条数
a1.channels.c1.capacity = 500000
#flume事务控制所需要的缓存容量1000条event
a1.channels.c1.transactionCapacity = 1000

#source channel sink cooperation
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

创建脚本flume_start.sh,用于启动Flume Agent

#!/bin/bash
/opt/pkg/flume-1.9.0/bin/flume-ng agent --conf ./conf/ -f ./conf/log2hdfs.conf --name a1 -Dflume.root.logger=INFO,console

编写停止Flume脚本 flume_stop.sh,停止Flume

#!/bin/bash

JAR="flume"

#停止flume函数
echo "begin to stop flume process.."
num=$(ps -ef|grep java|grep $JAR|wc -l)
echo "当前已经启动的flume进程数:$num"
if [ "$num" != "0" ];then
   #正常停止flume
   ps -ef|grep java|grep $JAR|awk '{print $2;}'|xargs kill -9
   echo "进程已经关闭..."
else
   echo "服务未启动,无须停止..."
fi

编写重启Flume脚本 flume-log2hdfs.sh,综合了前两个脚本

#!/bin/bash

#先停止正在启动的flume
./flume_stop.sh

nohup ./flume_start.sh > nohup_output.log 2>&1 &
echo "启动flume成功……"

后台管理界面点击启动FLume采集
file

查看滚动日志是否成功上传到HDFS系统

file

异常: 日志收集失败,报错:

2021-03-09 22:38:50,834 (SinkRunner-PollingRunner-DefaultSinkProcessor) [ERROR - org.apache.flume.sink.hdfs.HDFSEventSink.process(HDFSEventSink.java:459)] process failed
java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V

原因: flume/lib/guava-xxx.jar 和 hadoop自带的jar包发生冲突

解决: 将flume/lib下的guava包删除或者改名, 只保留hadoop的版本即可

Views: 143

电商日志分析项目 – 01 环境搭建和项目部署

一、CentOS7下MySQL-5.7使用yum方式安装:


Centos7的MySQL安装

卸载mariaDb

mysql被oracle收购后为了防止mysql有可能变成闭源,因此mysql创始人maria就开源做了一个mariaDb, centos7是自带使用了这个数据库的.因此安装mysql之前,应当首先卸载mariadb数据库:

$ sudo yum list installed | grep mariadb    #检查mariadb是否已安装

$ sudo yum list installed | grep mariadb
mariadb-libs.x86_64                     1:5.5.56-2.el7                 @anaconda

$ sudo yum -y remove mariadb*    #全部卸载

同理如果是已经安装过其他版本的MySQL,安装新的版本之前也需要按照如上方法进行卸载。

安装MySQL

下载mysql的YUM源: https://dev.mysql.com/downloads/repo/yum/

YUM源的官方安装说明:https://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/

下载源mysql的YUM源,官网提供的是最新的MySQL8.0的源,内含其他较低版本的源

wget -P /home/hadoop/softwares https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm  --no-check-certificate

由于我们是下载到/home/hadoop/softwares目录下,所以先切换到该目录下:

cd /home/hadoop/softwares

安装mysql的YUM源:

sudo rpm -ivh mysql80-community-release-el7-3.noarch.rpm

检查mysql的YUM源是否安装成功:

sudo yum repolist enabled | grep mysql

mysql-connectors-community/x86_64       MySQL Connectors Community           175
mysql-tools-community/x86_64            MySQL Tools Community                120
mysql80-community/x86_64                MySQL 8.0 Community Server           211

选择要启用的mysql版本

查看源里包含的mysql版本,执行:

sudo yum repolist all | grep mysql

mysql-cluster-7.5-community/x86_64 MySQL Cluster 7.5 Community      禁用
mysql-cluster-7.5-community-source MySQL Cluster 7.5 Community - So 禁用
mysql-cluster-7.6-community/x86_64 MySQL Cluster 7.6 Community      禁用
mysql-cluster-7.6-community-source MySQL Cluster 7.6 Community - So 禁用
mysql-cluster-8.0-community/x86_64 MySQL Cluster 8.0 Community      禁用
mysql-cluster-8.0-community-source MySQL Cluster 8.0 Community - So 禁用
mysql-connectors-community/x86_64  MySQL Connectors Community       启用:    175
mysql-connectors-community-source  MySQL Connectors Community - Sou 禁用
mysql-tools-community/x86_64       MySQL Tools Community            启用:    120
mysql-tools-community-source       MySQL Tools Community - Source   禁用
mysql-tools-preview/x86_64         MySQL Tools Preview              禁用
mysql-tools-preview-source         MySQL Tools Preview - Source     禁用
mysql55-community/x86_64           MySQL 5.5 Community Server       禁用
mysql55-community-source           MySQL 5.5 Community Server - Sou 禁用
mysql56-community/x86_64           MySQL 5.6 Community Server       禁用
mysql56-community-source           MySQL 5.6 Community Server - Sou 禁用
mysql57-community/x86_64           MySQL 5.7 Community Server       禁用
mysql57-community-source           MySQL 5.7 Community Server - Sou 禁用
mysql80-community/x86_64           MySQL 8.0 Community Server       启用:    211
mysql80-community-source           MySQL 8.0 Community Server - Sou 禁用

可以通过类似下面的语句来启动和禁用某些版本,比如这里是禁用默认启用的MySQL8.0的源,转而启用我们需要安装的MySQL5.7的源。

或者通过修改/etc/yum.repos.d/mysql-community.repo文件,改变默认安装的mysql版本。比如要安装5.7版本,将8.0源的enabled=1改成enabled=0,然后再将5.7源的enabled=0改成enabled=1即可。

sudo yum-config-manager --enable mysql57-community
sudo yum-config-manager --disable mysql80-community

要使用yum-config-manager命令, 需要先安装yum-utils: sudo yum install yum-utils

注意: 同一时间只允许enable一个MySQL版本。

如果只需要安装MySQL5.7的版本,也可以不看上面,直接本地安装指定的远程MySQL5.7源

yum localinstall https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm

查看当前的启用的 MySQL 版本:

yum repolist enabled | grep mysql

mysql-connectors-community/x86_64       MySQL Connectors Community           175
mysql-tools-community/x86_64            MySQL Tools Community                120
mysql57-community/x86_64                MySQL 5.7 Community Server           464

安装MySQL

sudo yum install -y mysql-community-server

已加载插件:fastestmirror
mysql-connectors-community                                             | 2.6 kB  00:00:00     
mysql-tools-community                                                  | 2.6 kB  00:00:00     
mysql57-community                                                      | 2.6 kB  00:00:00     
mysql57-community/x86_64/prima FAILED                                          
http://repo.mysql.com/yum/mysql-5.7-community/el/7/x86_64/repodata/cae8c564a11e5fca11dbe958c273358f206f1bba-primary.sqlite.bz2: [Errno 14] curl#7 - "Failed connect to repo.mysql.com:80; Connection refused"
正在尝试其它镜像。
mysql57-community/x86_64/primary_db                                    | 247 kB  00:00:00     
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
正在解决依赖关系
--> 正在检查事务
---> 软件包 mysql-community-server.x86_64.0.5.7.32-1.el7 将被 安装
--> 正在处理依赖关系 mysql-community-common(x86-64) = 5.7.32-1.el7,它被软件包 mysql-community-server-5.7.32-1.el7.x86_64 需要
--> 正在处理依赖关系 mysql-community-client(x86-64) >= 5.7.9,它被软件包 mysql-community-server-5.7.32-1.el7.x86_64 需要
--> 正在检查事务
---> 软件包 mysql-community-client.x86_64.0.5.7.32-1.el7 将被 安装
--> 正在处理依赖关系 mysql-community-libs(x86-64) >= 5.7.9,它被软件包 mysql-community-client-5.7.32-1.el7.x86_64 需要
---> 软件包 mysql-community-common.x86_64.0.5.7.32-1.el7 将被 安装
--> 正在检查事务
---> 软件包 mysql-community-libs.x86_64.0.5.7.32-1.el7 将被 安装
--> 解决依赖关系完成

依赖关系解决

==============================================================================================
 Package                      架构         版本                 源                       大小
==============================================================================================
正在安装:
 mysql-community-server       x86_64       5.7.32-1.el7         mysql57-community       173 M
为依赖而安装:
 mysql-community-client       x86_64       5.7.32-1.el7         mysql57-community        25 M
 mysql-community-common       x86_64       5.7.32-1.el7         mysql57-community       308 k
 mysql-community-libs         x86_64       5.7.32-1.el7         mysql57-community       2.3 M

事务概要
==============================================================================================
安装  1 软件包 (+3 依赖软件包)

总下载量:201 M
安装大小:875 M

....

已安装:
  mysql-community-server.x86_64 0:5.7.32-1.el7                                                

作为依赖被安装:
  mysql-community-client.x86_64 0:5.7.32-1.el7  
  mysql-community-common.x86_64 0:5.7.32-1.el7 
  mysql-community-libs.x86_64 0:5.7.32-1.el7 

启动MySQL服务

systemctl start mysqld.service # 或 service mysqld start

配置开机启动

systemctl enable mysqld.service

查看运行状态

systemctl status mysqld.service

mysql      2574      1  1 23:49 ?        00:00:00 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

查看到进程信息

netstat -anpl  | grep mysql

查看端口,可以看出mysql server的进程mysqld所使用的默认端口即3306

$ sudo netstat -anpl | grep tcp
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1412/sshd         
tcp        0     52 192.168.186.103:22      192.168.186.1:54058     ESTABLISHED 2287/sshd: hadoop 
tcp6       0      0 :::3306                 :::*                    LISTEN      2574/mysqld       
tcp6       0      0 192.168.186.103:3888    :::*                    LISTEN      2060/java         
tcp6       0      0 :::22                   :::*                    LISTEN      1412/sshd         
tcp6       0      0 :::37791                :::*                    LISTEN      2060/java         
tcp6       0      0 :::2181                 :::*                    LISTEN      2060/java 

找到临时密码

但是要登陆mysql,我们需要root密码,这个密码是安装时随机生成在MySQL的服务器日志中的

grep "temporary password" /var/log/mysqld.log

2020-02-26T17:05:45.104999Z 1 [Note] A temporary password is generated for root@localhost: bl/!6qaU.wuX

登录MySQL

# 回车后输入在日志中找到的临时root登录密码登录
mysql -u roop -p 

问题: 日志里没有找到临时密码, 或者密码不能登录,可能的原因就是之前安装过MySQL

解决办法:

sudo rm -rf /var/lib/mysql

再重启服务后就可以在日志文件中找到重新生成的临时密码了

systemctl restart mysqld.service

$ cat /var/log/mysqld.log | grep "temporary password"
2020-02-26T17:05:45.104999Z 1 [Note] A temporary password is generated for root@localhost: bl/!6qaU.wuX
2020-08-01T16:07:26.941916Z 1 [Note] A temporary password is generated for root@localhost: x/ttqh=)_6Z/

也可以直接使用明文密码登陆,像这样

mysql -uroop -p"x/ttqh=)_6Z/"

初始密码我们可以这样操作,因为很快我们会将将其改为其他的密码。

但是正常使用时不建议这样 不安全

黑客可以使用history命令查看到你在命令行的输入获取到你的MySQL的root密码

另外MySQL报错在/var下面的log目录下可以查看


如果是虚拟机环境为了方便可以选择配置跳过密码验证

vim /etc/my.cnf

添加以下代码

default-authentication-plugin=mysql_native_password #配置文件本来就有去掉注释即可
symbolic-links=0
skip-grant-tables #跳过密码验证

第一次登陆后系统会很快提示你修改掉默认密码

mysql> show databases;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

尝试修改密码(虚拟机可以设置简单密码,如果是购买的服务器则需设置复杂密码并修改默认端口号)

mysql> alter user 'root'@'localhost' identified by 'niit1234';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

密码安全策略

但是基于密码策略,所设置的密码必须要包含大小写字母、数字和字符。

修改策略并设置简单密码

将策略要求置为0(LOW),长度要求置为1

mysql> set global validate_password_policy=0;
mysql> set global validate_password_length=1;

关于密码安全策略:

通过show命令查看当前的策略

mysql> show variables like 'validate_password%';

+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password_check_user_name    | OFF    |
| validate_password_dictionary_file    |        |
| validate_password_length             | 8      |
| validate_password_mixed_case_count   | 1      |
| validate_password_number_count       | 1      |
| validate_password_policy             | MEDIUM |
| validate_password_special_char_count | 1      |
+--------------------------------------+--------+
7 rows in set (0.00 sec)

1) validate_password_policy:密码安全策略,默认MEDIUM策略

策略 检查规则
0 or LOW Length
1 or MEDIUM Length; numeric, lowercase/uppercase, and special characters
2 or STRONG Length; numeric, lowercase/uppercase, and special characters; dictionary file

2)validate_password_dictionary_file:密码策略文件,策略为STRONG才需要

3)validate_password_length:密码最少长度

4)validate_password_mixed_case_count:大小写字符长度,至少1个

5)validate_password_number_count :数字至少1个

6)validate_password_special_char_count:特殊字符至少1个

这样以后就可以使用新密码登陆了

开启远程登陆

mysql命令的-h选项可以设置需要远程登陆mysql的服务器的ip地址

如果是本地的话可以使用127.0.0.1或者直接省略

但是远程访问因为安全原因默认是关闭的

mysql> select Host,User from user;
+-----------+---------------+
| Host      | User          |
+-----------+---------------+
| localhost | mysql.session |
| localhost | mysql.sys     |
| localhost | root          |
+-----------+---------------+
3 rows in set (0.00 sec)

这里可以看到host都是localhost,这就是因为这些账号只有本地访问的权限

我们需要将root的访问权限扩大都允许任意方式访问(包括远程访问)

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY 'niit1234' WITH GRANT OPTION;

也可以创建一个专门用来支持远程访问的单独用户

GRANT ALL PRIVILEGES ON *.* TO 'remote'@'%' IDENTIFIED BY 'niit1234' WITH GRANT OPTION; 

如果你想允许用户myuser从ip为192.168.1.6的主机连接到mysql服务器,并使用mypassword作为密码

若你想限制能连接到mysql服务器的客户端所在的IP地址为'192.168.1.6'

并使用mypassword作为密码,则命令如下:

GRANT ALL PRIVILEGES ON . TO 'mysqluser'@'192.168.1.6'IDENTIFIED BY 'mypassword' WITH GRANT OPTION;

使修改生效

现在虽然修改了远程访问权限,但是还没有生效

我们需要刷新权限(或者重启服务),当然直接在mysql执行环境刷新权限是更好的方法

mysql>FLUSH PRIVILEGES;

然后我们可以试试使用navicat远程连接虚拟机中mysql试试

navicat虽然是收费的还是可以下载到破解的版本

最后一点

如果你的服务器开启了防火墙也可能导致远程无法连接

因为mysql默认使用3306端口,我们需要开放这个端口给mysql客户端连接

修改编码

默认安装的设置对中文的支持不好,一般需要修改成utf8,但这里我们修改成utf8mb4编码,因为它是uft8的超集,减少更多乱码的问题,也是推荐使用的编码,比如需要插入emoji字符在数据库中,utf8的显示就会出现问题,而utf8mb4则没有问题。

首先查看当前的编码:

mysql> show variables like '%char%';
+--------------------------------------+----------------------------+
| Variable_name                        | Value                      |
+--------------------------------------+----------------------------+
| character_set_client                 | utf8                       |
| character_set_connection             | utf8                       |
| character_set_database               | latin1                     |
| character_set_filesystem             | binary                     |
| character_set_results                | utf8                       |
| character_set_server                 | latin1                     |
| character_set_system                 | utf8                       |
| character_sets_dir                   | /usr/share/mysql/charsets/ |
| validate_password_special_char_count | 1                          |
+--------------------------------------+----------------------------+
9 rows in set (0.00 sec)

为了修改编码,我们需要修改mysql的核心配置文件如下:

[hadoop@hadoop000 download]$ sudo vim /etc/my.cnf

# For advice on how to change settings please see
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

log-error=/var/log/mysqld.log

# 默认服务器内部操作字符集
character-set-server=utf8mb4
# 默认服务器内部操作字符集校对规则
collation-server=utf8mb4_general_ci
# 默认的存储引擎
default-storage-engine=InnoDB
# 初始化连接时设置以下字符集:
# character_set_client
# character_set_results
# character_set_connection
init_connect='set names utf8mb4'

[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4
  • 30行以下为手动添加的配置

验证

mysql> show variables like '%char%';
+--------------------------------------+----------------------------+
| Variable_name                        | Value                      |
+--------------------------------------+----------------------------+
| character_set_client                 | utf8mb4                    |
| character_set_connection             | utf8mb4                    |
| character_set_database               | utf8mb4                    |
| character_set_filesystem             | binary                     |
| character_set_results                | utf8mb4                    |
| character_set_server                 | utf8mb4                    |
| character_set_system                 | utf8                       |
| character_sets_dir                   | /usr/share/mysql/charsets/ |
| validate_password_special_char_count | 1                          |
+--------------------------------------+----------------------------+
9 rows in set (0.00 sec)
  • character_set_client 是指客户端发送过来的语句的编码
  • character_set_database 是指服务器内部使用的编码
  • character_set_connection 是指mysqld收到客户端的语句后,要转换到的编码
  • character_set_results 是指server执行语句后,返回给客户端的数据的编码
  • character_set_system是元数据编码,无需修改
  • character_set_filesystem是文件系统的编码,2进制存储最有效,不能修改

rpm-bundle的离线安装

下载rpm-bundle包


$ wget http://mirrors.163.com/mysql/Downloads/MySQL-5.7/mysql-5.7.33-1.el7.x86_64.rpm-bundle.tar
$  tar xvf mysql-5.7.33-1.el7.x86_64.rpm-bundle.tar
$  mkdir mysql-jars
$  mv mysql-comm*.rpm mysql-jars/
$  cd mysql-jars/
$ ls
mysql-community-client-5.7.33-1.el7.x86_64.rpm
mysql-community-common-5.7.33-1.el7.x86_64.rpm
mysql-community-libs-5.7.33-1.el7.x86_64.rpm
mysql-community-libs-compat-5.7.33-1.el7.x86_64.rpm
mysql-community-server-5.7.33-1.el7.x86_64.rpm

依次手动安装

sudo rpm -ivh mysql-community-common-5.7.33-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-libs-5.7.33-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-libs-compat-5.7.33-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-client-5.7.33-1.el7.x86_64.rpm
sudo rpm -ivh mysql-community-server-5.7.33-1.el7.x86_64.rpm

CentOS7下MySQL-5.7使用yum方式卸载

1、停止MySQL
命令:systemctl stop mysqld
2、查看已安装的mysql
命令:rpm -qa | grep -i mysql
3、卸载mysql,依次卸载第2步骤所列出的有关MySQL的安装包,如
命令:yum remove -y mysql-community-server-5.6.36-2.el7.x86_64
4、删除mysql相关目录
1)使用命令查看mysql相关的文件目录:find / -name mysql
2)依次删除所查到的目录,命令:rm -rf /xxx/xxx/mysql

二、CentOS7下Nginx的安装:


Nginx安装

安装前确认是否已经安装过

sudo yum search nginx

Nginx文档http://nginx.org/en/docs/

Installation on Linux, nginx packages from nginx.org can be used.

Installation instructions
RHEL/CentOS
Debian
Ubuntu
SLES
Alpine

以 CentOS为例进行安装

Install the prerequisites:

sudo yum install yum-utils

To set up the yum repository, create the file named /etc/yum.repos.d/nginx.repo with the following contents:

sudo vi /etc/yum.repos.d/nginx.repo

内容如下:

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

By default, the repository for stable nginx packages is used. If you would like to use mainline nginx packages, run the following command:

sudo yum-config-manager --enable nginx-mainline

To install nginx, run the following command:

sudo yum install -y nginx

When prompted to accept the GPG key, verify that the fingerprint matches 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62, and if so, accept it.

常用命令

解释 命令
安装服务 yum install nginx
启动服务 service nginx start
停止服务 service nginx stop
重载服务 service nginx reload

配置完成后启动服务

sudo service nginx start

如果服务器已经启动,当配置发生变化可以直接使用重载服务来更新配置,运维常用,因为不需要停止服务就可以重载新的配置。

三、部署前端网站到nginx下


电商网站的静态文件都放在shop文件夹中,将此文件夹上传到虚拟机的/opt/data/目录下,

对nginx默认配置文件进行改名

$ cd /etc/nginx/conf.d/
$ mv default.conf shop.conf

修改如下


server {
    listen       80;
    server_name  hadoop100;
    root   /opt/data/;

    location /shop/ {
        index  index.html;
        access_log  /var/log/nginx/access.log  main;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

重新加载nginx配置,执行:

$ sudo nginx -s reload

在浏览器中验证下是否可以访问到网站,输入:

http://hadoop100/shop/

效果如下:
file

四、Tomcat的安装


准备:安装Java JDK1.8

这里安装openjdk是因为比较简单, 工作场合一定要使用oracle提供的jdk1.8

sudo yum -y install java-1.8.0-openjdk*

这样安装的好处就是环境变量都配好了

可以直接查看版本 java -version

Tomcat安装

下载页面: https://tomcat.apache.org/download-90.cgi

文档:https://tomcat.apache.org/tomcat-9.0-doc/index.html

下载链接

wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.41/bin/apache-tomcat-9.0.41.tar.gz

解压到后改名tomcat9

tar -zxvf apache-tomcat-9.0.41.tar.gz
mv apache-tomcat-9.0.41 /opt/pkg/tomcat9

由于tomcat的端口8080和大数据环境中的jetty端口冲突,这里修改tomcat的端口位18080

[hadoop@hadoop100 ~]$ cat /opt/pkg/tomcat9/conf/server.xml

...
    <Connector port="18080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

启动 进入 /bin目录下 运行startup.sh脚本文件

bin]$ ./startup.sh 
...
Tomcat started.

检查tomcat进程信息

$ bin]$ ps -ef | grep tomcat
hadoop    15142      1  1 14:41 pts/0    00:00:05 /home/hadoop/app/jdk1.8.0_211/bin/java -Djava.util.logging.config.file=/home/hadoop/app/tomcat9/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /home/hadoop/app/tomcat9/bin/bootstrap.jar:/home/hadoop/app/tomcat9/bin/tomcat-juli.jar -Dcatalina.base=/home/hadoop/app/tomcat9 -Dcatalina.home=/home/hadoop/app/tomcat9 -Djava.io.tmpdir=/home/hadoop/app/tomcat9/temp org.apache.catalina.startup.Bootstrap start
hadoop    15296  15064  0 14:47 pts/0    00:00:00 grep --color=auto tomcat

检查对应的监听端口信息

netstat -anpt | grep 15142

修改conf/tomcat-users.xml添加tomcat用户

添加如下内容
<!--  
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
  <user username="role1" password="tomcat" roles="role1"/>
-->
  <role rolename="manager-gui"/>
  <role rolename="manager-script" />
  <user username="admin" password="123123" roles="manager-gui,manager-script" />
</tomcat-users>

为了能够正常访问tomcat管理界面, 修改webapps/manager/META-INF目录下的context.xml,在allow行的末尾加上\d+.\d+.\d+.\d+表示允许所有主机访问。

<Context antiResourceLocking="false" privileged="true" >
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|\d+\.\d+\.\d+\.\d+" />
  <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>

重启tomcat9生效

bin/shutdown.sh
...
bin/startup.sh
6)验证,在浏览器输入: <code>http://hadoop100:8080/

或者在命令行里面输入:netstat -anop|grep 18080
file

五、电商后台系统部署到Tomcat服务器上


在MySQL创建数据库shop,将项目所需的sql数据导入,如:

mysql> source /opt/data/shop.sql

将代码导入到eclipse或者idea中

将代码数据库连接相关配置hibernate.properties做如下修改:

  • 修改数据库名及地址为服务器的数据库名及地址
  • 修改数据库用户明、密码为服务器的用户密码

file

选择export->war

上传war包至Linux服务器

修改war包名位university.war

将war包移动到Tomcat安装目录下的webapp目录下

启动或重启Tomcat

打开浏览器进行验证:
file

配置nginx反向代理

18080端口的访问方式不太方便,另外也需要解决nginx下部署的静态页面调用后台服务的跨域问题,这里需要设置nginx方向代理,修改nginx配置文件如下:

server {
    listen       80;
    server_name  hadoop100;
    root   /opt/data/;

    location /shop/ {
        index  index.html;
        access_log  /var/log/nginx/access.log  main;
    }

    location /university/ {
        proxy_pass http://hadoop100:18080/university/;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

重新加载nginx配置

sudo nginx -s reload

现在可以通过http://hadoop100/university/访问后台界面
file

如果访问失败可以查看错误日志

sudo vi /var/log/nginx/error.log 

如果发现502错误:

2020/11/18 16:12:39 [crit] 16376#16376: *1 connect() to 127.0.0.1:8080 failed (13: Permission denied) while connecting to upstream, client: 192.168.186.1, server: hadoop000, request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:8080/favicon.ico", host: "hadoop000", referrer: "http://hadoop000/"

此时需要考虑把linux操作系统默认的强制访问安全限制设置为禁用。

关闭SElinux即可

  1. 临时关闭 SElinux

    sudo setenforce 0
  2. 永久关闭 SElinux

    sudo vim /etc/selinux/config
    SELINUX=disabled

修改之后就可以正常访问了

通过http://hadoop100/shop访问前端界面,可以看见数据可以正常加载了.

file

至此商城项目的前后端就配置完了, 商城的nginx服务器日志保存在/var/log/nginx/access.log ,接下来我们将使用httpd提供的ab压测工具来快速生成大量访问日志.

Views: 144