小网站的容器化(下):网站容器化的各种姿势,先跟着撸一波代码再说!


作者 | 王洪鹏

责编 | Carol

出品 | CSDN云计算(ID:CSDNcloud)

封图| CSDN下载于视觉中国 

上篇文章:小网站的容器化(上) 中我们大致描述了下个人网站在日常维护中的痛点,文章的后半部分我们添加了一个纯静态网站容器化的简单示例。这篇文章作为上篇文章的续,我们接着看下静态网站容器化的剩余部分,以及常见个人动态网站容器化的部分。

 

静态网站容器化

上篇文章中,我们已经对静态网站的容器化过程以及容器化期间需要注意的事项做过描述,也添加过一个个人博客网站容器化的示例,但是这个示例仅仅是为静态网站容器化的过程作一个展现。我们知道,实际部署中,即使是纯静态页面的网站也不会那样进行部署,即直接将所有的内容,包括网站本身的文件和web server全部打包进一个容器里面。

这种部署方式,不利于网站后续的维护和更新,比如网站访问时我们一般对外提供的访问端口为80或者443,如果几个网站的web server对应的容器跑在一台宿主机上,几个容器都用80端口时会存在端口冲突的问题,而且在这种情况下我们需要为每个网站去专门配置一个域名。实际使用中我们一般不会这样进行操作,也不会为一个简单的个人简历静态网站去专门购买一个域名。

为解决这种问题,我们一般会在网站的web server前面再添加一个公共的反向代理组件,比如nginx,来作为多个个人小网站统一的访问入口,这样在对网站的内容进行更新时,我们只需要去更新反向代理之后对应的应用即可,不会因为某个网站的更新而影响到其他网站的正常访问。

另外,我们负载均衡之后的不同网站的应用此时可以配置80、443之外的端口,对外的80、443端口的监听放在负反向代理上即可,而且这种情况下只需要购买一个域名,然后将域名解析到公共的负载均衡地址,不同的网站采用不同的子域名即可,因此采用这种模式既利于网站的更新维护,且在经济方面更加的划算。下面就让我们一起看下这种情况下网站的容器化是如何进行的。

上篇文章中关于网站本身的打包及其镜像构建的过程我们已经详细的说过,包括git配置、Dockerfile书写、镜像构建、基本容器管理等,因此在此我们就不再赘述,接下来我们直接看上文中说到的反向代理的添加过程。 

在此我们假设我们给应用配置的端口为8080,然后配置nginx独占80端口,然后我们就可以根据客户端对域名的请求来将请求分发到对应的容器中的应用。 

首先我们用容器化的方式部署一个我们的网站,假设我们网站使用的web server 为tomcat,监听的端口使用默认的8080。

# 下载tomcat 镜像

[root@localhost ~]# docker pull hub.c.163.com/public/tomcat:7.0.28Trying to pull repository hub.c.163.com/public/tomcat ...7.0.28: Pulling from hub.c.163.com/public/tomcatf46924f139ed: Already existsa3ed95caeb02: Pull complete4849cac99801: Already exists5e90c4274a33: Pull completee8f49ae1f54f: Pull completecfd12ae39390: Pull complete1065252df5d5: Pull complete0fe337adb9c6: Pull complete9e5f36235195: Pull complete7edf271c9251: Pull completec255b3c6176a: Pull completed1aa8ac63c58: Pull completef9ab623b3035: Pull completef7da31d1f835: Pull complete48e150291322: Pull complete069d27b85888: Pull complete1835e80c6480: Pull completeDigest: sha256:dd6c708e981e61f6aae56dac2ef91a78b28e0589743b44b7f174a57b1f097154Status: Downloaded newer image for hub.c.163.com/public/tomcat:7.0.28

# 运行tomcat容器(应用代码在同一个容器中)

[root@localhost ~]# docker rm -f tomcat c64f076c3fda8d3183e570ad2af7253340de4fb48d098b6608f89fbf7715af0cc64f076c3fda8d3183e570ad2af7253340de4fb48d098b6608f89fbf7715af0c[root@localhost ~]# docker run --name tomcat -d -p 8080:8080  hub.c.163.com/public/tomcat:7.0.289a1e7c9909b8ce0299feecb5d424e16f8769476ef31d237ada8b8827c2106265[root@localhost ~]# hostname -I192.168.19.128 192.168.122.1 172.17.0.1

# 查看下端口是否已经在正常监听

[root@localhost ~]# netstat -anupt | grep 8080tcp6       0      0 :::8080                 :::*                    LISTEN      48830/docker-proxy

直接用容器所在机器的IP加8080端口访问,看下网站对应的容器是否已经运行起来:

可以看到此时网站对应的应用已经运行起来了,接下来我们配置下nginx反向代理。

在配置nginx的反向代理之前,第一步我们需要先下载、部署下nginx,在此我们直接以官网文档中的提供的方式进行部署:

# 安装依赖工具

[root@localhost ~]# yum install -y yum-utils 

# 配置yum 源,新建一个名为nginx.repo的配置文件

[root@localhost ~]# vim /etc/yum.repos.d/nginx.repo

加入如下yum配置:

[nginx-stable]name=nginx stable repobaseurl=http://nginx.org/packages/centos/$releasever/$basearch/gpgcheck=1enabled=1gpgkey=https://nginx.org/keys/nginx_signing.keymodule_hotfixes=true[nginx-mainline]name=nginx mainline repobaseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/gpgcheck=1enabled=0gpgkey=https://nginx.org/keys/nginx_signing.keyetodule_hotfixes=true

# 清空本地缓存

[root@localhost ~]# yum clean allLoaded plugins: fastestmirror, langpacksCleaning repos: Ceph Ceph-noarch ceph-source epel kubernetes nginx-stableCleaning up everythingCleaning up list of fastest mirrors

# 安装nginx

[root@localhost ~]# yum install -y nginxLoaded plugins: fastestmirror, langpacksLoading mirror speeds from cached hostfile 

# 运行nginx

[root@localhost ~]# systemctl start nginx 

# 确认nginx是否可以正常的运行起来

[root@localhost ~]# systemctl status nginx● nginx.service - nginx - high performance web serverLoaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)Active: active (running) since Thu 2020-03-19 03:46:00 PDT; 6s agoDocs: http://nginx.org/en/docs/Process: 27957 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)Main PID: 27958 (nginx)Memory: 2.9MCGroup: /system.slice/nginx.service├─27958 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf└─27959 nginx: worker processMar 19 03:46:00 localhost.localdomain systemd[1]: Starting nginx - high performance web server...Mar 19 03:46:00 localhost.localdomain systemd[1]: PID file /var/run/nginx.pid not readable (yet?) after start.Mar 19 03:46:00 localhost.localdomain systemd[1]: Started nginx - high performance web server.

# 配置开机自启动,防止服务器重启后服务挂掉的情况

[root@localhost ~]# systemctl enable nginxCreated symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.

Nginx正常运行起来的话,通过访问服务器的IP地址,可以查看到如下页面:

虽然web server tomcat 和反向代理nginx已经运行起来,但是默认情况下nginx中的配置是没有指向我们的web server tomcat的,因此我们接下来需要我们进行一些相关的配置,在此我们假设刚刚tomcat应用的域名为test.tomcat.com。

修改nginx配置,nginx默认配置文件为/etc/nginx/nginx.conf,在nginx配置文件中添加如下配置,将访问test.tomcat.com的请求转向我们网站应用对应的tomcat容器: 

首先我们需要在nginx的配置文件的路径/etc/nginx/conf.d下新建一个vhost.conf配置文件,这个配置文件就是用来配置我们网站反向代理的配置文件(不建议直接在nginx的默认配置文件/etc/nginx/nginx.conf 中进行配置,建议为每个vhost配置单独的配置文件): 

# 新建配置文件

[root@localhost ~]# cd /etc/nginx/conf.d[root@localhost conf.d]# lsdefault.conf[root@localhost conf.d]# vim vhost.conf

在打开的新配置文件中添加如下配置信息:

server{listen 80;server_name test.tomcat.com;location / {proxy_pass http://127.0.0.1:8080;}}

修改完成后,保存下配置。 

上述配置大意为,监听来自80端口的访问,如果访问的域名是test.tomcat.com则将请求全部转发到http://127.0.0.1:8080,也就是转发到我们tomcat 应用容器。 

Nginx配置完成后,需要reload后者重启下nginx服务,配置才能生效:

[root@localhost conf.d]# nginx -s reload

或者:

[root@localhost conf.d]# systemctl restart nginx[root@localhost conf.d]# systemctl status  nginx

接下来访问下nginx的80端口看下是否可以将请求转发到我们的8080端口的tomcat容器,访问nginx之前我们需先配置下本地的hosts,实际配置中一般大家都给自己的网站都购买了域名,这样的话实际配置时可省略掉这一步骤,配置hosts如下:

##### self test

192.168.19.128  test.tomcat.com

访问nginx中配置的域名:

截图中可以看到已经返回了tomcat的数据,说明nginx的反向代理到后端的tomcat 8080端口已经配置成功了。

动态网站容器化

 

以上是对静态网站静态化的一个简单说明,实际使用中,即使个人网站一般也很少做成静态网站这种形式,所以接下来我们看下常见的个人站点的容器化的过程。

1. Node.JS 站点容器化 

在描述Node.JS站点的容器化之前我们先在容器所在的虚拟机上部署一个简单的node.js运行环境和node.js应用。

Node.js 的整个安装部署非常简单,node.js 官网为我们提供了多种安装部署方式,在此我们以二进制包安装的方式为例看下具体的安装过程: 

# 下载node.js

[root@localhost ~]# wget https://nodejs.org/dist/v10.9.0/node-v10.9.0-linux-x64.tar.xz

# 解压安装包

[root@localhost ~]# tar xvf node-v10.9.0-linux-x64.tar.xz -C /usr/local

# 查看node.js文件

[root@localhost ~]# tar xvf node-v10.9.0-linux-x64.tar.xz -C /usr/local

[root@localhost ~]# ls /usr/local/node-v10.9.0-linux-x64/

bin  CHANGELOG.md  include  lib  LICENSE  README.md  share

[root@localhost ~]# ls /usr/local/node-v10.9.0-linux-x64/bin

node  npm  npx

可以看到默认情况下不仅node本身的进程已经给我们装上了,包管理工具npm默认也已经安装好了。 

# 配置下软连接,方便后续使用

[root@localhost ~]# ln -s /usr/local/node-v10.9.0-linux-x64/bin/node /usr/local/bin

[root@localhost ~]# ln -s /usr/local/node-v10.9.0-linux-x64/bin/npm /usr/local/bin

# 查看node版本

[root@localhost ~]# node -v

v10.9.0

接下来我们写个node.js 简单示例来作为我们的应用。 

新建app.js,加入示例代码:

var http = require('http');http.createServer(function (request, response) {// 发送 HTTP 头部// HTTP 状态值: 200 : OK// 内容类型: text/plainresponse.writeHead(200, {'Content-Type': 'text/plain'});// 发送响应数据 "Hello World"response.end('Hello World\n');}).listen(8888);// 终端打印如下信息console.log('Server running at http://127.0.0.1:8888/');

从文件的注释部分也能看出,我们是起了一个HTTP 服务器,监听端口为8888,接下来我们运行下这段代码:

[root@localhost ~]# node app.js

Server running at http://127.0.0.1:8888/

从日志提示我们可以看出此时HTTP Server已经在运行中了,接下来我们访问下这个Server,看下能否访问:

能正常访问到,则说明我们在虚拟机上的node已经正常跑起来了。 

刚刚我们是在前台运行的我们的node程序,前台运行程序适合临时测试下程序,如果是长期运行的程序一般都是建议在后台跑,在此我们以nohup这个工具为例,将程序在后台运行一下:

[root@localhost ~]# nohup node app.js  &> app.log &

[1] 128553
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]#

[root@localhost ~]# netstat -anupt | grep 8888

tcp6       0      0 :::8888                 :::*                    LISTEN      128553/node

这样程序已经在后台运行起来,不再占据前端,我们也不用担心接下来的操作过程中因为误操作会将程序意外退出。 

前面的访问我们也看到了,我们的HTTP server 默认监听的是8888端口,因此我们也需要用nginx做下反向代理。假设我们node.js 站点的域名是test.nodejs.com,和上文中tomcat站点的配置一样,首先我们需要先在nginx中新建一个网站的配置文件,由于上文中tomcat站点已经新建了一个单独的配置文件,在此我们不再重复进行新建,使用已经新建的即可。

修改/etc/nginx/conf.d/vhost.conf文件,加入对node.js站点的配置:

[root@localhost ~]# vim /etc/nginx/conf.d/vhost.conf

修改后内容如下:

 

在此我们给node.js站点配置的域名为test.node.com,实际使用中不需要重新为node申请域名,直接使用一个tomcat站点的子域名即可。

# 重启nginx 服务

[root@localhost ~]# systemctl restart nginx 

# 查看nginx状态

[root@localhost ~]# systemctl status  nginx

● nginx.service - nginx - high performance web serverLoaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)Active: active (running) since Sun 2020-03-29 21:50:24 PDT; 6h agoDocs: http://nginx.org/en/docs/Process: 10503 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)Process: 128736 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)Main PID: 128737 (nginx)CGroup: /system.slice/nginx.service├─128737 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf└─128738 nginx: worker processMar 29 21:50:23 localhost.localdomain systemd[1]: Starting nginx - high performance web server...Mar 29 21:50:24 localhost.localdomain systemd[1]: Started nginx - high performance web server.

和前文中tomcat的反向代理配置一样,我们需要先为node.js 站点的域名配置下hosts,具体如下:

192.168.19.128  test.node.com

浏览器访问test.node.com

上图中可以看出,node.js站点的反向代理已经配置成功了,node.js站点可以直接通过nginx的80端口进行访问了。

2. WordPress 站点容器化

在个人网站搭建工具中,WordPress 是非常受大众欢迎的,因此使用WordPress搭建的个人站点不在少数,接下来我们会一起看下WordPress 站点的容器化。

细心的读者可能会发现前面的两个示例中我们并未提及每个网站必备的组件—数据库,因为数据库的容器化比较特殊,因此我们单独拿出来在WordPress站点的例子中描述下。 

前面的实例中我们在打包镜像时直接将代码、配置文件等一起打包到了镜像里面,这种方式在无状态的服务这种情况时是可以的,但如果是mysql数据库这种有状态服务的情况这种打包镜像的方式很显然就不行了,这种情况下直接将正在运行的容器保存为镜像主要存在两个问题:

(1) 数据库类这种无状态应用一般都需要账号密码信息进行鉴权,我们将这些信息配置到应用的配置文件中,如果将这些文件打包到镜像里面,然后将其push到公有的镜像仓库,则其他人可以通过下载我们上传的镜像来查看到我们的数据库账号信息。

(2) 容器是无状态的,如果我们重启容器或者容器被意外的删除,则我们运行起容器后新写入的数据会丢失,包括们存储在mysql数据库中的数据。 

好在Docker 为我们提供了volume这种产品功能,利用volume我们可以将容器所在宿主机上的某个目录挂载到容器中,通过这种方式将容器中的目录和容器所在宿主机上的目录建立一种绑定关系。通过这种方式,容器中MySQL写的数据就会被同步到宿主机的目录之上,这样当我们重启容器或者删除容器时容器运行后新写入的数据就不会丢失。

需要注意的是,挂载了vloume的容器,在进行镜像的保存时并不会将vloume中的数据保存到镜像中,因此在更新容器后注意还需要再次挂载下我们的volume。

接下来我们具体看下wordpress站点的容器化过程,wordpress在此我们以4.5.2为例。

  # 首先我们需要先获取下wordpress镜像

  [root@localhost ~]# docker pull hub.c.163.com/public/wordpress:4.5.2

Trying to pull repository hub.c.163.com/public/wordpress ...4.5.2: Pulling from hub.c.163.com/public/wordpressf46924f139ed: Already existsa3ed95caeb02: Pull complete4849cac99801: Already exists682d1e7cffd4: Pull complete162c309da2f9: Pull complete2161e9680cdd: Pull complete43391942ffef: Pull completed77d4c0e8fd0: Pull complete6a6f091f97d8: Pull complete53fa8ad0f2eb: Pull complete28ee09fdd4e4: Pull completedf176ee322b5: Pull complete44104685ee03: Pull complete1822edc7ae75: Pull completeecfd62e25a20: Pull completef3c6ecfde54e: Pull complete81113ad0b0e3: Pull completebb5c02f581db: Pull complete1a10055e720e: Pull completeDigest: sha256:894e1cd6b398ea895f94d803e6de71c12c9b68fa3663e10c96ed4bc22adcb54aStatus: Downloaded newer image for hub.c.163.com/public/wordpress:4.5.2

  # 镜像下载完成后,我们运行下容器,看下载的镜像是否正常

[root@localhost ~]# docker run --name wordpress -p 8082:80  -d hub.c.163.com/public/wordpress:4.5.2ae09f3291607130bd78186caadb02d0ba8af5d684b82165ab19cd89c1a145833 

因为nginx默认已经监听了80端口,为防止出现端口冲突,此处我们将apache web server 的端口映射为8082,容器名字为wordpress。 

# 查看端口是否在监听了

[root@localhost ~]# netstat -anupt | grep 8082tcp6       0      0 :::8082                 :::*                    LISTEN      4259/docker-proxy

# 进入容器看下wordpress的各个组件是否已经运行起来了

[root@localhost ~]# docker exec -ti wordpress bashroot@ae09f3291607:/var/www# ps auxUSER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMANDroot          1  0.0  0.0   4192   576 ?        Ss   04:36   0:00 /bin/sh -c /etc/init.d/mysql start && /tmp/entrypoint-wd.sh apache2 && /usr/sbin/sshd -D || /usr/sbin/sshd -Droot         34  0.0  0.0   4192   708 ?        S    04:36   0:00 /bin/sh /usr/bin/mysqld_safemysql       363  0.1  6.4 371504 64136 ?        Sl   04:36   0:00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin --user=mysql --pid-file=/var/run/mysqld/mysqld.pidroot        364  0.0  0.0   4100   632 ?        S    04:36   0:00 logger -t mysqld -p daemon.errorroot        617  0.0  0.9 158924  9588 ?        Ss   04:37   0:00 /usr/sbin/apache2 -k startroot        619  0.0  0.3  49952  3028 ?        S    04:37   0:00 /usr/sbin/sshd -Dwww-data    621  0.0  0.6 158956  6008 ?        S    04:37   0:00 /usr/sbin/apache2 -k startwww-data    622  0.0  0.6 158956  6008 ?        S    04:37   0:00 /usr/sbin/apache2 -k startwww-data    623  0.0  0.6 158956  6008 ?        S    04:37   0:00 /usr/sbin/apache2 -k startwww-data    624  0.0  0.6 158956  6008 ?        S    04:37   0:00 /usr/sbin/apache2 -k startwww-data    625  0.0  0.6 158956  6008 ?        S    04:37   0:00 /usr/sbin/apache2 -k startroot        626  2.3  0.1  17836  1840 ?        Ss   04:41   0:00 bashroot        631  0.0  0.1  15320  1136 ?        R+   04:41   0:00 ps aux

可以看到当前镜像默认使用的是LAMP架构,且各个组件已经在运行中。然后我们看下mysql默认的数据目录,从上面的信息中可以看到为:/var/lib/mysql。需要注意的是我们不能直接将宿主机上的目录挂载到我们的wordpress容器中的mysql数据存放路径,因为直接挂载会导致容器中MySQL 的数据被覆盖掉,为避免MySQL的数据被覆盖,在此我们先将已经存在的mysql数据拷贝出来,然后再进行宿主机目录的挂载。然后接下来我们将这个目录和宿主机的目录关联一下。 

# 本地新建下wordpress中mysql的数据目录

[root@localhost ~]# mkdir /data/mysql

# 将wordpress容器中已经存在的mysql数据拷贝到宿主机上

[root@localhost ~]# docker cp  wordpress:/var/lib/mysql/ /data/mysql[root@localhost ~]# ls /data/mysqldebian-5.5.flag  ibdata1  ib_logfile0  ib_logfile1  mysql  mysql_upgrade_info  performance_schema  wordpress

# 删掉当前已经在运行的wordpress容器

[root@localhost ~]# docker rm -f wordpressWordpress[root@localhost ~]# docker psCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES[root@localhost ~]#

# 重新运行wordpress容器并挂载mysql的数据目录

[root@localhost ~]# docker run --name wordpress -v /data/mysql/:/var/lib/mysql/ -p 8082:80  hub.c.163.com/public/wordpress:4.5.2 

和前面的静态站点以及node.js程序一样,由于我们监听的8082端口是非80端口,因此还需要为wordpress站点配置下反向代理。 

具体过程和前面配置node.js站点的一样,假设我们的wordpress站点的域名为test.wordpress.com,然后直接在现存的vhosts文件中进行配置即可,具体如下:

# 修改nginx中vhost.conf配置

[root@localhost ~]# vim /etc/nginx/conf.d/vhost.conf

修改后的配置信息如下:

server{listen 80;server_name test.tomcat.com;location / {proxy_pass http://127.0.0.1:8080;}}server{listen 80;server_name test.node.com;location / {proxy_pass http://127.0.0.1:8888;}}server{listen 80;server_name test.wordpress.com;location / {proxy_pass http://127.0.0.1:8082;}}

# 重启nginx服务

[root@localhost ~]# systemctl restart nginx

[root@localhost ~]# systemctl status  nginx

● nginx.service - nginx - high performance web serverLoaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)Active: active (running) since Thu 2020-04-02 04:37:09 PDT; 6s agoDocs: http://nginx.org/en/docs/Process: 47753 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)Process: 47774 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)Main PID: 47775 (nginx)CGroup: /system.slice/nginx.service├─47775 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf└─47776 nginx: worker processApr 02 04:37:09 localhost.localdomain systemd[1]: Starting nginx - high performance web server...Apr 02 04:37:09 localhost.localdomain systemd[1]: Started nginx - high performance web server.

 

和前面的过程一样,在访问站点之前我们需要先配置下hosts文件(真实环境中购买了域名且加了域名的解析可忽略), 具体如下:

192.168.19.128  test.tomcat.com

192.168.19.128  test.node.com

192.168.19.128  test.wordpress.com 

接下来我们看下容器化后的wordpress 站点是否可以正常访问:


容器化小结

 

本文是上篇《小网站的容器化》的续篇,在此我们主要看了下常见的个人站点的容器化过程,并列举了node.js和WordPress 两个站点实例。

既然容器化可以为我们带来这么多的方便之处,那还是建议那些苦于网站更新的小伙伴们尝试一下容器化,同时也借此了解下容器云领域的广阔天地。

 

同时,欢迎所有开发者扫描下方二维码填写《开发者与AI大调研》,只需2分钟,便可收获价值299元的「AI开发者万人大会」在线直播门票!

推荐阅读:你知道吗?其实 Oracle 直方图自动统计算法存在这些缺陷!(附验证步骤)
你公司的虚拟机还闲着?基于 Jenkins 和 Kubernetes 的持续集成测试实践了解一下!一站式杀手级 AI 开发平台来袭!告别切换零散建模工具那些神一样的程序员
比特币当赎金,WannaRen 勒索病毒二度来袭!通过 Python 代码实现时间序列数据的统计学预测模型
真香,朕在看了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/518372.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云应用高可用 AHAS 正式商用,可一键提升云上应用可用性

在分布式架构环境下,服务间的依赖日益复杂,可能没有人能说清单个故障对整个系统的影响,构建一个高可用的分布式系统面临着很大挑战。 7月17日,阿里云应用高可用服务AHAS 正式商用,包含架构感知、流控降级和故障演练三…

机器学习在高德起点抓路中的应用实践

导读:高德地图作为中国领先的出行领域解决方案提供商,导航是其核心用户场景。路线规划作为导航的前提,是根据起点、终点以及路径策略设置,为用户量身定制出行方案。 起点抓路,作为路线规划的初始必备环节,…

css-阴影和超链接伪类

阴影和超链接伪类 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* 默认的颜色 */a{text-decoration: none; /* 去掉下划线 */color: #000000; /* 修改颜色 */}…

时尚电商新赛道:揭秘 FashionAI 技术

雷音是阿里巴巴研究员、淘系技术部 FashionAI 负责人&#xff0c;在淘系技术嘉年华硅谷站&#xff0c;他分享了《时尚电商新赛道— FashionAI 中的技术》 &#xff0c;旨在揭秘&#xff1a;从面向机器学习的知识重建切入&#xff0c;提出了在 AI 能力的推动下&#xff0c;让人值…

MQ 技术产品井喷,今天来详聊一下腾讯开源消息中间件 TubeMQ | 原力计划

作者 | kimmking来源 | CSDN博客&#xff0c;责编 | 夕颜出品 | CSDN&#xff08;ID:CSDNnews&#xff09;随着分布式技术的发展&#xff0c;MQ技术产品也出现井喷。目前除了各类常用的MQ&#xff0c;比如Apache的ActiveMQ&#xff0c;Kafka&#xff0c;Pulsar&#xff0c;Rock…

MongoDB compact 命令详解

为什么需要 compact 一图胜千言 remove 与 drop 的区别 MongoDB 里删除一个集合里所有文档&#xff0c;有两种方式 db.collection.remove({}, {multi: true})&#xff0c;逐个文档从 btree 里删除&#xff0c;最后所有文档被删除&#xff0c;但文件物理空间不会被回收db.col…

css-背景图片和渐变

背景图片 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* 边框 border 1px粗细 solid样式 red颜色*/div{width: 1000px;height: 700px;border: 1px solid red;/*…

GitOps 初探

前言 GitOps 的概念最初来源于 Weaveworks 的联合创始人 Alexis 在 2017 年 8 月发表的一篇博客 GitOps - Operations by Pull Request。文章介绍了 Weaveworks 的工程师如何以 Git 作为事实的唯一真实来源&#xff0c;部署、管理和监控基于 Kubernetes 的 SaaS 应用。 随后&…

老码农吐血建议:2020年,低于1w的程序员要注意了...

最近在知乎上&#xff0c;关于AI的这个话题又被顶起来&#xff0c;其中&#xff0c;这条回答让人印象深刻&#xff1a;在这短短的一条信息里&#xff0c;无疑显示出&#xff1a;AI行业缺人&#xff0c;高端岗位80万年薪恐怕也招不来&#xff01;小编上周在一个AI群里&#xff0…

重磅!容器集群监控利器 阿里云Prometheus 正式免费公测

Prometheus 作为容器生态下集群监控的首选方案&#xff0c;是一套开源的系统监控报警框架。它启发于 Google 的 borgmon 监控系统&#xff0c;并于 2015 年正式发布。2016 年&#xff0c;Prometheus 正式加入 Cloud Native Computing Foundation&#xff0c;成为受欢迎度仅次于…

Archsummit 2019重磅分享|闲鱼Flutter&FaaS云端一体化架构

作者&#xff1a;闲鱼技术&#xff0d;国有   讲师介绍 国有&#xff0c;闲鱼架构团队负责人。在7月13号落幕的2019年Archsummit峰会上就近一年来闲鱼在Flutter&FaaS一体化项目上的探索和实践进行了分享。 传统NativeWeb服务端混合开发的挑战 随着无线&#xff0c;Io…

Spring Cloud 云架构下的微服务架构:部门微服务(Dept)

作者 | springML来源 | CSDN 博客 责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;封图| CSDN下载于视觉中国 对于 Rest 基础架构实现处理是 SpringCloud 核心所在&#xff0c;其基本操作形式在 SpringBoot 之中已经有了明确的讲解&#xff0c;…

并发模式与 RPS 模式之争,性能压测领域的星球大战

本文是《如何做好性能压测》系列专题分享的第四期&#xff0c;该专题将从性能压测的设计、实现、执行、监控、问题定位和分析、应用场景等多个纬度对性能压测的全过程进行拆解&#xff0c;以帮助大家构建完整的性能压测的理论体系&#xff0c;并提供有例可依的实战。 该系列专…

Akka in Schedulerx2.0

1. 前言 Schedulerx2.0是阿里中间件自研的基于akka架构的新一代分布式任务调度平台&#xff0c;提供定时、任务编排、分布式跑批等功能&#xff0c;具有高可靠、海量任务、秒级调度等能力。 本篇文章以Schedulerx2.0为例子&#xff0c;介绍akka的应用场景&#xff0c;希望能给…

java.sql.SQLException: The server time zone value ‘???ú±ê×??±??‘ is unrecognized or represents more

【报错信息】 【百度翻译】 服务器时区值???????无法识别或表示多个时区。如果要利用时区支持&#xff0c;必须配置服务器或JDBC驱动程序&#xff08;通过ServerTimeZone配置属性&#xff09;&#xff0c;以使用更具体的时区值 【解决方法】 数据库连接配置conf.xml(…

【从入门到放弃-Java】并发编程-锁-synchronized

简介 上篇【从入门到放弃-Java】并发编程-线程安全中&#xff0c;我们了解到&#xff0c;可以通过加锁机制来保护共享对象&#xff0c;来实现线程安全。 synchronized是java提供的一种内置的锁机制。通过synchronized关键字同步代码块。线程在进入同步代码块之前会自动获得锁…

Redis 学习之一招击穿自己的系统,附送 N 个击穿解决大礼包 | 原力计划

作者 | Mark_MMXI来源 | CSDN博客&#xff0c;责编 | 夕颜出品 | CSDN&#xff08;ID:CSDNnews&#xff09;缓存的存在是为了在高并发情形下&#xff0c;缓解DB压力&#xff0c;提高业务系统体验。业务系统访问数据&#xff0c;先去缓存中进行查询&#xff0c;假如缓存存在数据…

阿里巴巴王坚:用数据来改变世界

“传统信息化建设都是从无到有&#xff0c;加了杆子和机器&#xff0c;但是新一代数字建设就是从有到无&#xff0c;缴费的机器没有了&#xff0c;你回家缴&#xff0c;杆子没有了&#xff0c;你回家缴。” 7月21日&#xff0c;阿里巴巴技术委员会主席王坚在2019年中国电子政务…

Knative Service 之流量灰度和版本管理

本篇主要介绍 Knative Serving 的流量灰度&#xff0c;通过一个 rest-api 的例子演示如何创建不同的 Revision、如何在不同的 Revision 之间按照流量比例灰度。 部署 rest-api v1 代码 测试之前我们需要写一段 rest-api 的代码&#xff0c;并且还要能够区分不同的版本。下面…

在生产环境中使用 Sentinel

文章目录一、安装zookeeper1. linux环境2. windows环境2. 安装并启动zkui二、编译打包2.1. 拉取项目2.2. 启动2.3. 登录 sentinel2.4. 登录zkui2.5. 重启Sentinel2.6. 删除Sentinel的流控规则三、将客户端和zk打通3.1. 引入依赖3.2. 配置3.3. 启动springboot3.4. sentinel控制台…