• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
isuning
博客园    首页    新随笔    联系   管理    订阅  订阅
Docker系列教程(8)实战Web服务

Web服务

Docker 安装 Nginx

Nginx 是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP 服务 。

查看可用的 Nginx 版本

访问 Nginx 镜像库地址: https://hub.docker.com/_/nginx?tab=tags。

$ docker search nginx
$ docker pull nginx:1.10
$ docker images
#	先运行一次容器(为了拷贝配置文件)
$ docker run -e TZ="Asia/Shanghai" -p 8080:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx  \
-d nginx:1.10

# 将容器内的配置文件拷贝到指定目录:
$ docker container cp nginx:/etc/nginx /mydata/nginx/
# 修改文件名称
$ mv nginx conf
# 终止并删除容器
$ docker stop nginx
$ docker rm

# 再次启动
$ docker run -p 8080:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx  \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10

参数说明:

  • –name nginx-test:容器名称。
  • -p 8080:80: 端口进行映射,将本地 8080 端口映射到容器内部的 80 端口。
  • -d nginx: 设置容器在在后台一直运行。

最后我们可以通过浏览器可以直接访问 8080 端口的 nginx 服务

反向代理

反向代理就是当请求访问你的代理服务器时,代理服务器会对你的请求进行转发,可以转发到静态的资源路径上去,也可以转发到动态的服务接口上去。下面我们以对域名进行代理为例,来讲讲如何进行静态代理和动态代理。

静态代理

静态代理就是将请求代理到不同的静态资源路径上去,这里我们将对**docs.sh.com**的请求代理到我的文档项目中,对**mall.sh.com**的请求代理到mall的前端项目中。

  • 首先我们修改下本机的host文件:
192.168.6.132 docs.sh.com
192.168.6.132 mall.sh.com
  • 然后将我们的文档项目和mall前端项目上传到nginx的html目录中去,并进行解压操作:
  • 在/mydata/nginx/conf/conf.d文件夹中添加配置文件docs.conf对文档项目进行反向代理
server {
    listen       80;
    server_name  docs.sh.com; #修改域名

    location / {
        root   /usr/share/nginx/html/docs; #代理到docs文件夹中
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}
  • 在/mydata/nginx/conf/conf.d文件夹中添加配置文件mall.conf对mall的前端项目进行反向代理:
server {
    listen       80;
    server_name  mall.sh.com; #修改域名
 
    location / {
        root   /usr/share/nginx/html/mall; #代理到mall文件夹中
        index  index.html index.htm;
    }
 
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
 
}
  • 重启nginx服务:
docker restart nginx

通过docs.sh.com即可访问到我们的文档项目了

通过mall.sh.com即可访问到mall的前端项目了

动态代理

动态代理就是把代理服务器的请求转发到另一个服务上去,这里我们将对**api.sh.com**的请求代理到mall-admin的后台服务上去。

  • 首先我们修改下本机的host文件,添加如下规则:
192.168.6.132 api.sh.com
  • 在/mydata/nginx/conf/conf.d文件夹中添加配置文件api.conf对将请求代理到远程的mall-admin服务上去:
server {
    listen       80;
    server_name  api.sh.com; #修改域名
 
    location / {
        proxy_pass   http://120.27.63.9:8080; #修改为代理服务地址
        index  index.html index.htm;
    }
 
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
 
}

重启动nginx服务后,通过api.sh.com/swagger-ui.html即可访问到mall-admin的API文档页面了

文件压缩

如果我们租用了一个带宽很低的服务器,网站访问速度会很慢,这时我们可以通过让nginx开启GZIP压缩来提高网站的访问速度。这里我们以mall的前端项目为例来演示下它的提速效果。

首先我们对nginx进行限速操作,限制每个连接的访问速度为128K来建立一个比较慢的访问场景;

修改mall.conf配置文件,进行限速操作:

server {
    listen       80;
    server_name  mall.macrozheng.com;
 
    limit_rate 128k; #限制网速为128K
 
    location / {
        root   /usr/share/nginx/html/mall;
        index  index.html index.htm;
    }
 
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
 
}

对mall的前端项目mall.sh.com进行访问,我们可以发现网站中有个js文件比较大,需要加载12s

  • 修改/mydata/nginx/conf目录下的nginx.conf配置文件,开启GZIP压缩;
http {
 
    gzip on; #开启gzip
    gzip_disable "msie6"; #IE6不使用gzip
    gzip_vary on; #设置为on会在Header里增加 "Vary: Accept-Encoding"
    gzip_proxied any; #代理结果数据的压缩
    gzip_comp_level 6; #gzip压缩比(1~9),越小压缩效果越差,但是越大处理越慢,所以一般取中间值
    gzip_buffers 16 8k; #获取多少内存用于缓存压缩结果
    gzip_http_version 1.1; #识别http协议的版本
    gzip_min_length 1k; #设置允许压缩的页面最小字节数,超过1k的文件会被压缩
    gzip_types application/javascript text/css; #对特定的MIME类型生效,js和css文件会被压缩
 
    include /etc/nginx/conf.d/*.conf;
}

再次对mall的前端项目mall.sh.com进行访问,我们可以发现js文件已经被压缩,加载时间缩短到3.88s,提速3倍左右

nginx返回请求头中添加了Content-Encoding: gzip的信息

地址重写

有的时候我们的网站更换了域名,但还有用户在使用老的域名访问,这时可以通过nginx的地址重写来让用户跳转到新的域名进行访问。

比如说原来我们用的docs.sh.com这个域名不用了,现在改成www.sh.com了来访问文档项目了;

修改docs.conf配置文件,将地址带参数重写到新地址:

server {
    listen       80;
    server_name  docs.macrozheng.com; 
 
    rewrite "^/(.*)$" http://www.sh.com/$1; #地址重写到新地址
 
    location / {
        root   /usr/share/nginx/html/docs; 
        index  index.html index.htm;
    }
 
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
 
}

此时访问旧域名docs.sh.com会直接跳转到www.sh.com去。

按目录划分项目

有时候我们需要使用同一个域名来访问不同的前端项目,这时候就需要通过子目录来区分前端项目了。

  • 比如说我们需要按以下路径来访问各个前端项目;
www.sh.com #访问文档项目
www.sh.com/admin #访问后台项目
www.sh.com/app #访问移动端项目
  • 修改配置文件,添加不同的location规则,要注意alias和root指令的区别,root不会将location配置的路径去掉,而alias会将location配置的路径去掉。
server {
    listen       80;
    server_name  www.sh.com;
 
    location / {
        root   /usr/share/nginx/html/www;
        index  index.html index.htm;
    }
 
    location /admin {
        alias   /usr/share/nginx/html/admin;
        index  index.html index.htm;
    }
 
    location /app {
        alias   /usr/share/nginx/html/app;
        index  index.html index.htm;
    }
 
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
负载均衡

upstream模块的负载均衡算法主要有三种,轮调(round-robin)、ip哈希(ip_hash)和 最少连接(least_conn)三种。

ip_hash:基于客户端IP地址完成请求的分发,它可以保证来自于同一个客户端的请求始终被转发至同一个upstream服务器;
round-robin : 基于 权重的轮询。不需要明确注明,在各个节点中设置 权重 weight 即可。
least_conn: 最少连接调度算法

upstream backend{

        server ip1:port1;

        server ip2:port2 backup; #热备当第一台服务器出问题时,启用第二台服务器

        ip_hash;#nginx 会让相同客户端ip请求相同的服务器,session保持需要

  }
server {
    listen    8080;
    server_name locahost
    location /api/ {
        proxy_pass  https://backend;
        proxy_redirect     off;
        proxy_set_header   Host             $host;        # 传递域名
        proxy_set_header   X-Real-IP        $remote_addr; # 传递ip
        proxy_set_header   X-Scheme         $scheme;      # 传递协议
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
client_max_body_size 10m; #允许客户端请求的最大单文件字节数 client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
 }}

Docker 安装 Tomcat

$ docker search tomcat
$ docker pull tomcat:8.5.40
$ docker images|grep tomcat
$ docker run -e TZ="Asia/Shanghai" --name tomcat  -d -p 8080:8080 -v /mydata/tomcat/webapps:/usr/local/tomcat/webapps -v /mydata/tomcat/logs:/usr/local/tomcat/logs 
-v /etc/localtime:/etc/localtime tomcat:8.5.40

Docker 安装 Jenkins

Jenkins是开源CI&CD软件领导者,提供超过1000个插件来支持构建、部署、自动化,满足任何项目的需要。我们可以用Jenkins来构建和部署我们的项目,比如说从我们的代码仓库获取代码,然后将我们的代码打包成可执行的文件,之后通过远程的ssh工具执行脚本来运行我们的项目。

$ docker pull jenkins/jenkins:lts
$ docker run -p 8080:8080 -p 50000:5000 --name jenkins \
-u root \
-v /mydata/jenkins_home:/var/jenkins_home \
-d jenkins/jenkins:lts
Jenkins的配置
  • 运行成功后访问该地址登录Jenkins,第一次登录需要输入管理员密码:http://192.168.6.132:8080/

  • 使用管理员密码进行登录,可以使用以下命令从容器启动日志中获取管理密码:

docker logs jenkins
  • 选择安装插件方式,这里我们直接安装推荐的插件

  • 安装完成后,创建管理员账号

  • 进行实例配置,配置Jenkins的URL

  • 点击系统管理->插件管理,进行一些自定义的插件安装

    • 远程使用ssh的插件:SSH plugin
    • 角色权限查询(运维使用)
  • 通过系统管理->全局工具配置来进行全局工具的配置,比如maven的配置

  • 在系统管理->系统配置中添加全局ssh的配置,这样Jenkins使用ssh就可以执行远程的linux脚本了

角色权限管理

我们可以使用Jenkins的角色管理插件来管理Jenkins的用户,比如我们可以给管理员赋予所有权限,运维人员赋予执行任务的相关权限,其他人员只赋予查看权限。

在系统管理->全局安全配置中启用基于角色的权限管理

进入系统管理->Manage and Assign Roles界面

添加角色与权限的关系

给用户分配角色

部署SpringBoot应用

这里我们使用mall-learning项目中的mall-tiny-jenkins模块代码来演示下如何使Jenkins一键打包部署SpringBoot应用

  • 上传代码

首先我们需要安装Gitlab(当然你也可以使用Github或者Gitee),然后将mall-tiny-jenkins中的代码上传到Gitlab中去。

要将pom.xml中的dockerHost地址改成你自己的Docker镜像仓库地址。

 <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.1.0</version>
                <executions>
                    <execution>
                        <id>build-image</id>
                        <phase>package</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <imageName>mall-tiny/${project.artifactId}:${project.version}							</imageName>
                    <dockerHost>http://192.168.6.132:2375</dockerHost>
                    <baseImage>java:8</baseImage>
                    <entryPoint>["java", "-jar","/${project.build.finalName}.jar"]
                    </entryPoint>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        </plugins>
    </build>
  • 执行脚本准备

将mall-tiny-jenkins.sh脚本文件上传到/mydata/sh目录下,脚本内容如下

#!/usr/bin/env bash
app_name='mall-tiny-jenkins'
docker stop ${app_name}
echo '----stop container----'
docker rm ${app_name}
echo '----rm container----'
docker run -e TZ="Asia/Shanghai" -p 8088:8088 --name ${app_name} \
--link mysql:db \
-v /etc/localtime:/etc/localtime \
-v /mydata/app/${app_name}/logs:/var/logs \
-d mall-tiny/${app_name}:1.0-SNAPSHOT
echo '----start container----'
  • 给.sh脚本添加可执行权限:
$ chmod +x ./mall-tiny-jenkins.sh 

windows下的.sh脚本上传到linux上使用,需要修改文件格式,否则会因为有特殊格式存在而无法执行

:set ff 
#修改文件格式为unix
:set ff=unix 
#保存并退出
:wq

  • 执行.sh脚本,测试使用,可以不执行

    $ ./mall-tiny-jenkins.sh
    
在Jenkins中创建执行任务

首先我们需要新建一个任务

设置任务名称后选择构建一个自由风格的软件项目

然后在源码管理中添加我们的git仓库地址

添加一个凭据,也就是我们git仓库的账号密码

之后我们需要添加一个构建,选择调用顶层maven目标,该构建主要用于把我们的源码打包成Docker镜像并上传到我们的Docker镜像仓库去.

选择我们的maven版本,然后设置maven命令和指定pom文件位置

maven 3.6.3
clean package
${WORKSPACE}/pom.xml

之后添加一个执行远程shell脚本的构建,用于在我们的镜像打包完成后执行启动Docker容器的.sh脚本

ssh地址
root@ip
•	需要设置执行的shell命令如下:
/mydata/sh/mall-tiny-jenkins.sh

之后点击保存操作,我们的任务就创建完成了,在任务列表中我们可以点击运行来执行该任务

我们可以通过控制台输出来查看整个任务的执行过程

posted on 2022-05-01 22:17  吕布辕门  阅读(50)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3