服务器到底帮我们做了一件什么事(比如说tomcat)

	首先,知道一句话,tomcat是一个servlet容器就够了。。。。

什么是servlet

我们写的controller类其实也是一个被高级封装了的servlet类,servlet说白了就是继承了servlet接口的的一个我们自己写的类,例如 public class main implements Servlet,这个接口在javax.servlet包中;这个接口有init(),service(),destroy()三个特别重要的方法要我们实现的;
参考springmvc是如何简化servlet实现类编写的深度解析

servlet和服务器的联系

看图说话:
在这里插入图片描述
来解析一番:(特别是第四步尤其重要,这些http请求响应啊作为参数传入给servlet实现类的)
1.Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
  ②装载并创建该Servlet的一个实例对象。
  ③调用Servlet实例对象的init()方法。
  ④创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
  ⑤WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。

知道servlet怎么被调用之后深入了解tomcat的工作原理

看图说话:
server->service->(connector,container,Loader,Realm,JMX,Jsper,Session,Naming,Logging…)
在这里插入图片描述
container->Engine->host(这里的虚拟机不是JVM啊)->Context->wrapper

在这里插入图片描述

解析一波::
Server:指的就是整个 Tomcat 服 务器,包含多组服务,负责管理和 启动各个 Service,同时监听 8005 端口发过来的 shutdown 命令,用 于关闭整个容器 ;
Service:Tomcat 封装的、对外提 供完整的、基于组件的 web 服务, 包含 Connectors、Container 两个 核心组件,以及多个功能组件,各 个 Service 之间是独立的,但是共享 同一 JVM 的资源 ;
Connector:Tomcat 与外部世界的连接器,监听固定端口接收外部请求,传递给 Container,并 将 Container 处理的结果返回给外部;
Container:Catalina,Servlet 容器,内部有多层容器组成,用于管理 Servlet 生命周期,调用 servlet 相关方法。
Loader:封装了 Java ClassLoader,用于 Container 加载类文件;
Realm:Tomcat 中为 web 应用程序提供访问认证和角色管理的机制;
JMX:Java SE 中定义技术规范,是一个为应用程序、设备、系统等植入管理功能的框架,通过 JMX 可以远程监控 Tomcat 的运行状态;
Jasper:Tomcat 的 Jsp 解析引擎,用于将 Jsp 转换成 Java 文件,并编译成 class 文件。 Session:负责管理和创建 session,以及 Session 的持久化(可自定义),支持 session 的集
群。
Pipeline:在容器中充当管道的作用,管道中可以设置各种 valve(阀门),请求和响应在经由管 道中各个阀门处理,提供了一种灵活可配置的处理请求和响应的机制。
Naming:命名服务,JNDI, Java 命名和目录接口,是一组在 Java 应用中访问命名和目录服务的 API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象,目录服务也是一种命名 服务,对象不但有名称,还有属性。Tomcat 中可以使用 JNDI 定义数据源、配置信息,用于开发 与部署的分离。

Engine:Servlet 的顶层容器,包含一 个或多个 Host 子容器;
Host:虚拟主机,负责 web 应用的部 署和 Context 的创建;
Context:Web 应用上下文,包含多个 Wrapper,负责 web 配置的解析、管 理所有的 Web 资源;
Wrapper:最底层的容器,是对 Servlet 的封装,负责 Servlet 实例的创 建、执行和销毁。

注意::每一个service里面只有一个Engine,每一个servlet是加载到wraper里面的。。

看看tomcat的启动过程:
在这里插入图片描述

参考原文

Servlet 生命周期:
在这里插入图片描述
Servlet 是用 Java 编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。
请求到达 server 端,server 根据 url 映射到相应的 Servlet
判断 Servlet 实例是否存在,不存在则加载和实例化 Servlet 并调用 init 方法
Server 分别创建 Request 和 Response 对象,调用 Servlet 实例的 service 方法(service 方法 内部会根据 http 请求方法类型调用相应的 doXXX 方法)
doXXX 方法内为业务逻辑实现,从 Request 对象获取请求参数,处理完毕之后将结果通过 response 对象返回给调用方
当 Server 不再需要 Servlet 时(一般当 Server 关闭时),Server 调用 Servlet 的 destroy() 方 法。
load on startup
当值为 0 或者大于 0 时,表示容器在应用启动时就加载这个 servlet; 当是一个负数时或者没有指定时,则指示容器在该 servlet 被选择时才加载; 正数的值越小,启动该 servlet 的优先级越高;
single thread model
每次访问 servlet,新建 servlet 实体对象,但并不能保证线程安全,同时 tomcat 会限制 servlet 的实例数目
最佳实践:不要使用该模型,servlet 中不要有全局变量

了解host的作用以及涉及到的环回地址(127.0.0.1)和本机地址的区别

上面就一句话:host是负责web应用的部署,那他是怎么映射到机器上的,一般默认为localhost,但是可以更改其他的名字,比如说是这个web项目的名字,只要在
hosts具体的文件地址在C:\Windows\System32\drivers\etc文件夹下,并且需要使用管理员身份打开。加一个:
在这里插入图片描述
这个是域名服务的原理,通过这个域名可以定位到那台机器的服务,再加上端口号就可以定位到这台机器的哪个进程的服务,比如我们租用了阿里云的服务器,相当于就是在他服务器上加一个域名的映射。
无论是localhost还是自己配置的host虚拟主机名(如我自己配置的ui),在浏览器看来都是一个域名,那么域名都是需要进行DNS解析的。但是我们自己配置的域名在DNS服务器是没有的,因为我们没有注册,因此虽然我们在tomcat中进行了配置,但在网络上是没有我们的域名的。我们需要在本地进行配置,而hosts文件正是起到了这样的作用。当用户在浏览器中输入一个URL地址时,系统会首先自动从Hosts文件中寻找对应的域名映射的IP地址,一旦找到,浏览器会立即向该ip地址发送http请求报文。如果没有找到,则浏览器会向本地DNS服务器请求IP地址解析(如果本地DNS服务器无法解析,则会向根DNS服务器请求…

那么127.0.0.1和本机的ip(192.168.11.1)有什么区别呢
127.0.0.1是一个环回地址:
环回地址是主机用于向自身发送通信的一个特殊地址(也就是一个特殊的目的地址)。
可以这么说:同一台主机上的两项服务若使用环回地址而非分配的主机地址,就可以绕开TCP/IP协议栈的下层。(也就是说:不用再通过什么链路层,物理层,以太网传出去了,而是可以直接在自己的网络层,运输层进行处理了)
本机的ip是一个和本机网卡绑定的网络地址:
参考

局部Ip和公网的Ip

局部的ip就是本机的ip,也就是私网ip,也就是通过ipconfig打印出来的的ip例如192.168.11.1
网络的的ip,就是机器接入网络时分配的ip地址,这个就是公网Ip,可以在百度敲打ip地址,就可以显示本机的公网ip,我们在查看连接的wifi的属性的时候查看的是这个具有路由功能的电脑的本机ip…这个不是公网ip;

其实Ip是一个很广的概念
私网IP、公网IP、IPV4、IPV6。从而得知,IPV4是一个版本,而IP是一个很大的概念,所以他们有着本质上的区别。那么我们常见的IP有私有网IP(又称:局域网IP)和公有网IP(又称:广域网IP),这个两种IP的肯定是不相同。IP的版本又分IPV4和IPV6。

公有地址(Public address)由Inter NIC(Internet Network Information Center因特网信息中心)负责。这些IP地址分配给注册并向Inter NIC提出申请的组织机构。通过它直接访问因特网。
   私有地址(Private address)属于非注册地址,专门为组织机构内部使用。

以下列出留用的内部私有地址

A类 10.0.0.0–10.255.255.255

B类 172.16.0.0–172.31.255.255

C类 192.168.0.0–192.168.255.255
在这里插入图片描述
在这里插入图片描述

服务下的高并发:tomcat在高访问量下是如何新建线程的

提供服务的软件基本都是一样的,例如,每有一个mysql客户端连接就会新建一个线程有线程来处理一个用户,例如数据库连连接池,其实底层就是一个线程连接池,设置了连接数量,超过了就阻塞。
java为服务器提供的处理的高并发的方式有4种,但是tomcat采用最好的两种(默认是用线程池,还有一种是NIO技术,可以在server.xml方式进行切换)这些都是写tomcat的人已经写好了的,不用在controller类里面新建线程池
首先,服务器的实现不止有这两种方式。

先谈谈题主说的这两种服务器模型:

1、收到一个请求就处理,这个时候就不能处理新的请求,这种为阻塞 这个是单线程模型,无法并发,一个请求没处理完服务器就会阻塞,不会处理下一个请求。一般的服务器不会使用这种方式实现。

2、收到一个请求就新开一个线程去处理任务,主线程返回,继续处理下一个任务,这种为非阻塞
首先纠正一个错误,这并不是非阻塞,它也是阻塞的。相对第一个模型来说,它解决了主线程阻塞的问题,有了一定程度的并发量,但是在每个新开的线程中还是阻塞的。如果100个人同时访问,将会开100个线程,那1000个人,10000个人呢?频繁开关线程很消耗资源,这样实现的服务器性能依然不高。

除了上面的两种方式,接下来的说说其他更好的方式:

3、类似2的模型,但是不是每次收到请求就开一个新的线程,而是使用线程池
如果不了解线程池,你可能会了解数据库连接池,由于频繁创建、关闭数据库连接会消耗资源,所以会用数据库连接池来保存一定数量的连接,如果需要就从连接池里取连接,不需要则放回连接池,不在频繁创建。线程池也是一样的道理,线程池管理多线程,性能比频繁创建线程高得多。这种方式实现的服务器性能会比2高。不过,它依然是阻塞的。线程池的线程数量通常有限制的,如果所有线程都被阻塞(例如网速慢,或者被人恶意占用连接),那么接下来的请求将会排队等待。

4、基于Java NIO实现的服务器模型
上面说到的几种模型,都是基于BIO(阻塞IO)。而NIO则是非阻塞IO,它是基于IO多路复用技术(例如Reactor模式)实现,只需要一个线程或者少量线程,就可以处理大量请求。从性能上来说NIO实现的服务器并发性一般大于BIO,所以可以实现高性能的服务器。如果感兴趣,可以学习一些基于NIO的网络编程框架,例如Netty、MINA。

最后,回答一下题主说到的Tomcat。Tomcat运行可以选择BIO或者NIO模型,原理分别对应上面的3和4两种方式。Tomcat默认是BIO方式运行,如果想要换成NIO,可以配置server.xml:

<Connector port=“8080” protocol=“org.apache.coyote.http11.Http11NioProtocol” …/>
从性能上考虑建议使用NIO。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值