狂神Docker通俗易懂学习笔记3

7 篇文章 0 订阅
6 篇文章 0 订阅

docker命令小节

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

作业练习

Docker 安装Nginx

命令如下:

01 、搜索镜像 search 建议大家去docker搜索,可以看到帮助文档
02、下载镜像 pull
03、运行测试
参数说明
-d 后台运行
–name 给容器命名
-p 宿主机端口:容器内部端口
在这里插入图片描述
端口暴露的概念
在这里插入图片描述

Docker 安装tomcat

官方使用:
docker run -it --rm tomcat:9.0
注:我们之前的启动都是后台,停止容器之后,容器还是可以查到,docker run -it --rm tomcat:9.0 一般用来测试,用完即删,

1、下载启动
docker pull tomcat
2、启动运行
docker run -d -p 3355:8080 --name tomcat01 tomcat
3、测试外网访问没有问题,报错404,只是不完整
在这里插入图片描述
4、进入容器
docker exec -it tomcat01 /bin/bash
5、发现问题,
a、linux命令少了,
b、没有webapps. 阿里云镜像的原因,默认是最小的镜像,所有不必要的都剔除掉
root@a1f3af4f9f22:/usr/local/tomcat/webapps# cp …/webapps.dist/* .
在这里插入图片描述
思考问题:我们以后要部署项目,如果每次都 要进入容器是不是十分麻烦,我们要是可以在容器外部提供一个映射路径,webapps, 我们在外部放置项目就自动同步到内部就好了,

Docker 部署ES(elastic)+Kibana

  • es 暴露端口很多
  • es 特别耗内存
  • es 的数据一般需要放置到安全目录!挂载
  • –net somenetwork 网络配置
  • 在这里插入图片描述
  • 启动elasticsearch:
    docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e “discovery.type=single-node” elasticsearch:7.9.3

** 启动了 linux就卡住了, docker stats 查看cpu状态
** es是十分耗内存,
** 查看docker stats
** 测试一下es 是够成功了,
** 赶紧关闭,增加内存的限制
@@内存限制: -e ES_JAVA_OPTS="-Xms64m -Xms512m"

docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e “discovery.type=single-node” -e ES_JAVA_OPTS="-Xms64m -Xms512m" elasticsearch:7.9.3
在这里插入图片描述

Docker镜像讲解

镜像是什么
  • 镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时库,环境变量和配置文件, 所有的应用,直接打包docker镜像,就可以直接跑起来
  • 如何得到镜像呢?
    ---- 从远程仓库下载
    ---- 朋友拷贝给你
    ---- 自己制作一个镜像Dockerfile
Docker镜像加载原理
  • UnionFS(联合文件系统)
    我们下载的时候看到的一层层就是这个!
    UnionFS(联合文件系统) :Union(联合文件系统)是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem). Union文件系统是Docker 镜像的基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作一种具体的应用镜像。
    特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有的底层的文件和目录

  • Docker镜像加载原理
    docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS
    bootfs(boot file system)主要包含bootloader 和kernel, bootloader 主要是引导加载kernel, Linux刚启动的时候会加载bootfs文件系统,在Docker镜像的最底层是bootfs. 这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核,当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs
    rootfs(root file system) ,在bootfs之上,包含的就是典型的Linux系统 中 /dev 、/proc 、 /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,CentOS等等

在这里插入图片描述
平时我们安装进虚拟机的CentOS都好几个G,为什么Docker这里才200M
在这里插入图片描述

对于一个精简的OS , rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了因为底层直接用Host的kernel,自己只需要提供rootfs就可以了,由此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行生版可以公用bootfs

虚拟机是分钟级别的,容器是秒级的!

分层理解
  • 分层的镜像

  • 我们可以云下载一个镜像,注意观察下载的日志输出,可以看到是一层一层的在下载

  • 在这里插入图片描述

  • 查看镜像分层的方式 可以通赤docker image inspetc命令查看 在这里插入图片描述

在这里插入图片描述
------思考:为什么Docker镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于是资源共享了比如有多个镜像都 从桢的Base镜像构建而来,寻么宿主机只需要在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的第每一层可以被共享

------理解:所有的Docker镜像都起始于一个基础镜像层,当时行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层,举一个简单的例子,假如基于Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层,如果在该镜像中添加Python包,就会在基础镜像之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三个镜像层,
该镜像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)

在这里插入图片描述
在添加额外的镜像层的同时,镜像始终保持是当前所有的镜像组合,这一点非常重要,下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件
在这里插入图片描述
上图中的镜像层跟之前的图中略有区别,主要目的是便于展示文件
下图中展示了一个稍微复杂的三层镜像,在外部看一整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版本
在这里插入图片描述
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件,这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。

------ Docker通存储引擎(新版本采用快照机制)的试来实现镜像层规栈,并保证多镜像层对外展示为统一的文件系统。

------ Linux上可用的存储引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于Linux中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
------ Docker在Windows上仅支持windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW[1]
下图展示了与系统显示相同的三层镜像,所有镜像层堆叠并合并,对外提供统一的视图在这里插入图片描述
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层就是我们通常说的容器层,容器之下都叫镜像层
在这里插入图片描述

commit镜像

docker commit 提交容器成了一个新的副本

命令和git原理类似
docker commit -m=“提交的描述信息” -a=“作者” 容器id 目标镜像名,[TAG]

实战测试

1、启动一个默认的tomcat
2、发现这个默认的tomcat 是没有webapps应用,镜像的原因官方的镜像默认webapps下面是没有文件 的
3、我自己拷贝进去了基本的文件
4、将我们操作过的容器通过commit 提交为一个镜像,我们以的一就使用我们修改过的镜像即可,这就是我们自己的一个修改的镜像

在这里插入图片描述
学习方式说明: 理解概念,但是一定要实践,最后实践和理论相结合一次搞定这个知识
如果你想要保存当前容器的状态,就可以通赤commit来提交,获得一个镜像,就好比我们以前学习过的VM快照

到了这里才算是入门

容器数据卷

什么是容器数据卷
  • docker 的理念回顾
    ------ 将应用和环境打包成一个镜像
    ------ 数据? 如果数据都在容器中,那么我们容器被删除,数据就会丢失! 需求:数据可以持久化
    MySQL,容器删除了,如比删库跑路了,需求:MySQL数据可以存储在本地!
    ------ 容器之间可以有一个数据共享技术,Docker容器中产生的数据同步到本地 ---------这就是卷技术
    ------ 目录的挂载,将我们容器的目录,挂载到Linux上面!
    在这里插入图片描述
    总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
使用数据卷

方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器目录 -p 主机端口:容器内端口
在这里插入图片描述
在这里插入图片描述
好处:我们以后修改只需要在本地修改即可,容器内会自动同步!

实战:安装MySQL

思考:MySQL的数据持久化的问题
------ 1、获取镜像:
[root@joboy home]# docker pull mysql:5.7

------2 、运行容器,需要做数据挂载! 安装启动mysql, 需要配置密码,这是要注意点!
在这里插入图片描述
这是官方文档---->官方命令:
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

参数说明:

-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
–name 容器名字

------ 3、启动我们的mysql

[root@joboy home]#docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

------ 4、启动之后我们在本地使用 sqlyog 来不接测试一下, sqlyog连接到服务器3310—3310和容器内的3306映射,这个时候我们就可以连接上了,本在测试创建一个数据库,查看一下我们映射的路径是否ok

在这里插入图片描述
映射结果:
在这里插入图片描述

具名挂载和匿名挂载

------ 匿名挂载
docker run -d -P --name nginx01 -v /etc/nginx nginx
------ 查看所有的volume 卷的情况
docker volume ls
在这里插入图片描述
------ 这里发现,这种就是匿名挂载,我们在-v只写了容器内的路径,没有写容器外的路径!
在这里插入图片描述

在这里插入图片描述
docker volume inspect juming_nginx
在这里插入图片描述
所有的docker 容器内的卷,沿岸有指定目录的情况下都是在 /var/lib/docker/volumes/****/_data
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况我们使用的是: 具名挂载
在这里插入图片描述
----- 如何确定是具名挂载还是匿名挂载,还是指定路径挂载
1、-v 容器内路径-------------------------------- # 匿名挂载
2、-v 卷名:容器内路径----------------------- # 具名挂载
3、-v /宿主机路径::容器内路径--------------- # 指定路径挂载!

 拓展:
 	通过 -v 容器内路径: ro rw 改变读写权限
 	ro:  readonly    # 只读
 	rw  readwrite   # 可读可写
 	注:一但这个设置了容器权限,容器对我们挂载出来的内容就有限定了
 	docker run -d -P --name  nginx03 -v juming_nginx:/etc/nginx nginx:ro
 	docker run -d -P --name  nginx03 -v juming_nginx:/etc/nginx nginx:rw
 	#  ro 只要看到ro 就说明这个路径只能通过宿主机来操作,容器内部是无法操作的!
初识Dockerfile

Dockerfile 就是用来构建docker镜像的构建文件! 命令脚本,先体验一下
--------通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层!
方式二 : 直接写Dockerfile
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
----------自己写的容器在这里插入图片描述
这个卷和外部一定有一个同步目录在这里插入图片描述

在这里插入图片描述
测试一下刚才的文件是否同步出去了
这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像,假设构建镜像的时候没有挂载卷,要手动镜像挂载, -v 卷名:容器内路径
在这里插入图片描述

数据卷容器

–多个mysql同步数据

先看下面的例子:两个docker 及以前数据同步
docker run -it --name docker02 --volumes-from docker01 80297b784621
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
—# 测试:可以删除docker01 , 查看一下docker02 和docker03是否还可以访问这个文件
—# 测试结果:测试结果依旧可以访问

在这里插入图片描述
下面来实现多个mysql现实数据共享
[root@joboy ~]# docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

[root@joboy ~]# docker run -d -p 3310:3306 l -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
– # 这个时候可以实现两个容器数据同步
结论: 容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止,但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!

DockerFile

dockerfile 是用来构建docker镜像的文件,命令参数脚本

构建步骤:
1、 编写一个dockfile文件
2、docker build 构建成了一个镜像
3、docker run 运行镜像
4、docker push 发布镜像(DockerHub 、阿里云镜像仓库)

查看一下我们的官方是怎么做的?

在这里插入图片描述

在这里插入图片描述
很多官方镜像都是基础包很多功能都没有,我们通常会自己搭建自己的镜像,
官方既然可以制作镜像,那我人也可以!

Dockfile构建过程
  • 1、每个保留关键字(指令)都是必须是大写字母

  • 2、执行从上到下顺序执行

  • 3、#表示注释

  • 4、每一个指令都会创建提交一个新的镜像层,并提交!

  • 5、dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockfile文件,这个文件十分简单!

  • Dock镜像逐渐成为企业交付的标准,,必须掌握,!

开发步骤: 开发、部署、运维。。。。 缺一不可

  • DockFile: 构建文件,定义了一切的步骤,源代码。
  • DockImages: 通过DockFile 构建生成的镜像,最终发布和运行的产品
  • Docker容器:容器就是镜像运行起来提供服务器
DockerFile的指令

FROM--------------- # 基础镜像,一切从这里开始构建
MAINTAINER---- # 镜像是谁写的,姓名+邮箱
RUN --------------- # 镜像构建的时候需要运行的命令
ADD --------------- # 步骤:tomcat镜像,这个tomcat压缩包,添加内容
WORKDIR--------- #镜像的工作目录
VOLUME---------- #挂载的目录
EXPOST----------- # 保留端口配置
CMD----------------- # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT---- # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD----------- # 当构建一个被继承 DockerFile 这个时候就会运行 ONBUILD 的命令,触发指令
COPY-----------------# 类似ADD 将我们文件拷贝到镜像中
ENV-------------------# 构建的时候设置环境变量
在这里插入图片描述

实战测试

Docker Hub中,99% 镜像都是从这个基础镜像过来的 FROM scratch, 然后配置需要的软件和配置来进行的构建在这里插入图片描述

------ 自己创建一个centos

  • 1、 编写自己的镜像
    在这里插入图片描述
    代码如下:

    FROM centos
    MAINTAINER pengpengzzp3344@126.com
    ENV MYPATH /uer/local
    WORKDIR $MYPATH
    RUN yum -y install vim
    RUN yum -y install net-tools
    EXPOSE 80
    CMD echo $MYPATH
    CMD echo “----end----”
    CMD /bin/bash

  • 2、 通过这个文件构建镜像
    命令 docker build -f dockerfile文件路径 -t 镜像名:[tag]

    [root@joboy dockerfile]# docker build -f mydockerfile_centos -t mycentos:1.0
    注释:最后一个点 “.” 不要忘记

  • 3、测试运行

  • 对比之前原生态centos
    在这里插入图片描述

  • 我们增加之后的镜像:
    在这里插入图片描述

  • 我们可以列出本地进行的变更历史
    在这里插入图片描述
    我们平时拿到一个镜像 ,可以研究一下它是怎么做的了


CMD 和ENTRYPOINT 区别

CMD -------------- # 指定这个容器启动的时候要运行的命令只有最后一个会生效,可被替代
ENTRYPOINT —#指定这个家口 启动的时候要运行的命令,可以追加命令

# 测试CMD:
 	编写dockerfile 文件
 	[root@joboy dockerfile]# vim dockerfile_cmd_test
    FROM centos
    CMD  ["ls","-a"]
  # 构建镜像
 	 [root@joboy dockerfile]# docker build -f dockerfile_cmd_test -t cmdtest .
 # run运行,发现我们的ls -a 命令生效
 	[root@joboy dockerfile]# docker run 5efed9aee7dc
 	.
	..
	.dockerenv
	bin
	dev
	etc
	home
	lib
	lib64
	lost+found
	media
	mnt
	opt
	proc
	root
	run
	sbin
	srv
	sys
	tmp
	usr
	var

# 想追加一个命令 -l    ls  -al
	[root@joboy dockerfile]# docker run 5efed9aee7dc -l
																																						docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.
	# cmd 情况下 -l 替换了CMD [ "ls" , "-a"  ] 命令,-l 不是命令所以报错
			root@joboy dockerfile]# docker run 5efed9aee7dc ls -al
			total 56
			drwxr-xr-x  1 root root 4096 Nov 20 11:59 .
			drwxr-xr-x  1 root root 4096 Nov 20 11:59 ..
			-rwxr-xr-x  1 root root    0 Nov 20 11:59 .dockerenv
			lrwxrwxrwx  1 root root    7 May 11  2019 bin -> usr/bin
			drwxr-xr-x  5 root root  340 Nov 20 11:59 dev
			drwxr-xr-x  1 root root 4096 Nov 20 11:59 etc
			drwxr-xr-x  2 root root 4096 May 11  2019 home
			lrwxrwxrwx  1 root root    7 May 11  2019 lib -> usr/lib
			lrwxrwxrwx  1 root root    9 May 11  2019 lib64 -> usr/lib64
			drwx------  2 root root 4096 Aug  9 21:40 lost+found
			drwxr-xr-x  2 root root 4096 May 11  2019 media
			drwxr-xr-x  2 root root 4096 May 11  2019 mnt
			drwxr-xr-x  2 root root 4096 May 11  2019 opt
			dr-xr-xr-x 94 root root    0 Nov 20 11:59 proc
			dr-xr-x---  2 root root 4096 Aug  9 21:40 root
			drwxr-xr-x 11 root root 4096 Aug  9 21:40 run
			lrwxrwxrwx  1 root root    8 May 11  2019 sbin -> usr/sbin
			drwxr-xr-x  2 root root 4096 May 11  2019 srv
			dr-xr-xr-x 13 root root    0 Nov 20 11:59 sys
			drwxrwxrwt  7 root root 4096 Aug  9 21:40 tmp
			drwxr-xr-x 12 root root 4096 Aug  9 21:40 usr
			drwxr-xr-x 20 root root 4096 Aug  9 21:40 var
			[root@joboy dockerfile]# 

测试ENTRYPOINT:

			[root@joboy dockerfile]# docker build -f dockerfile_cmd_entrypoint -t 
			Sending build context to Docker daemon  4.096kB
			Step 1/2 : FROM centos
			 ---> 0d120b6ccaa8
			Step 2/2 : ENTRYPOINT ["ls","-a"]
			 ---> Running in d2bc5a1555d7
			Removing intermediate container d2bc5a1555d7
			 ---> 8bc56be759ad
			Successfully built 8bc56be759ad
			Successfully tagged entrypoint_test:latest
			[root@joboy dockerfile]# docker run 8bc56be759ad
			.
			..
			.dockerenv
			bin
			dev
			etc
			home
			lib
			lib64
			lost+found
			media
			mnt
			opt
			proc
			root
			run
			sbin
			srv
			sys
			tmp
			usr
			var
			# 我们的追加命令, 是直接拼接在我们的 ENTRYPOINT 命令后面的
			[root@joboy dockerfile]# docker run 8bc56be759ad -l
			total 56
			drwxr-xr-x  1 root root 4096 Nov 20 12:07 .
			drwxr-xr-x  1 root root 4096 Nov 20 12:07 ..
			-rwxr-xr-x  1 root root    0 Nov 20 12:07 .dockerenv
			lrwxrwxrwx  1 root root    7 May 11  2019 bin -> usr/bin
			drwxr-xr-x  5 root root  340 Nov 20 12:07 dev
			drwxr-xr-x  1 root root 4096 Nov 20 12:07 etc
			drwxr-xr-x  2 root root 4096 May 11  2019 home
			lrwxrwxrwx  1 root root    7 May 11  2019 lib -> usr/lib
			lrwxrwxrwx  1 root root    9 May 11  2019 lib64 -> usr/lib64
			drwx------  2 root root 4096 Aug  9 21:40 lost+found
			drwxr-xr-x  2 root root 4096 May 11  2019 media
			drwxr-xr-x  2 root root 4096 May 11  2019 mnt
			drwxr-xr-x  2 root root 4096 May 11  2019 opt
			dr-xr-xr-x 94 root root    0 Nov 20 12:07 proc
			dr-xr-x---  2 root root 4096 Aug  9 21:40 root
			drwxr-xr-x 11 root root 4096 Aug  9 21:40 run
			lrwxrwxrwx  1 root root    8 May 11  2019 sbin -> usr/sbin
			drwxr-xr-x  2 root root 4096 May 11  2019 srv
			dr-xr-xr-x 13 root root    0 Nov 20 12:07 sys
			drwxrwxrwt  7 root root 4096 Aug  9 21:40 tmp
			drwxr-xr-x 12 root root 4096 Aug  9 21:40 usr
			drwxr-xr-x 20 root root 4096 Aug  9 21:40 var
			[root@joboy dockerfile]# 

总结:Dockerfile中很多命令都十分的相似,我们想要了解他们的区别,我们最好的学习就是对比他们然后测试结果!

实战:Tomcat镜像

1、准备镜像文件,tomcat 压缩包,jdk的压缩包

在这里插入图片描述

2、编写dockerfile文件,官方命名Dockerfile , buld会自动寻找这个文件,就不需要 -f 指定了

 FROM centos
MAINTAINER pengpeng<zzp3344@126.com>

COPY readme.txt  /uer/local/readme.txt

ADD jdk-8u11-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.40.tar.gz /usr/local

RUN yum -y update --nogpgcheck
RUN yum -y makecache --nogpgcheck
RUN yum -y install vim --nogpgcheck

ENV  MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH  $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.40
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.40
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.40/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.40/bin/logs/catalina.out

3、构建镜像

[root@joboy pengpeng]# docker build -t diytomcat .

4、启动镜像

docker run -d -p 9090:8080 --name pengpengcomcat2 -v  /home/pengpeng/build/tomcat/test:/usr/local/apache-tomcat-9.0.40/webapps/test  -v /home/pengpeng/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.40/logs diytomcat

5、访问测试
6、发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了!)

  <?xml version="1.0" encoding="UTF-8"?>
  <web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                               http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">

  </web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello 朋朋(runoob.com)</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("-------Hello The World  Hello pengpeng---------")
%>
</body>
</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值