前言
文本: 字符串
超文本:图片、音乐、视频、定位、地图等。
每种编程语言中的Socket类都是对TCP/IP协议的实现,HTTP协议就是规范如何在Socket上传输超文本数据的一种技术规范。
无论是Java/Golang/Python编程语言都可以实现HTTP协议中定义的规范,并构建出1个Web应用程序,对外提供Web服务。
实现同一个 目的方式,是不尽相同,但通过实现HTTP协议规范,构建出1个高性能、易于扩展的Web应用程序的目的是殊途同归的 。
以下将学习Java的Web开发技术。
一、Web开发概念
无论使用什么语言开发Web应用程序的目的都是一样的,使用了不同的工具而已。
除了学习各种工具本身之外,更应该学习不同工具,解决同一问题的思想。
1.Web基本概念
由于对以下一些概念的理解不深刻,我从使用Python Web再到Java Web开发的转换过程中,纠结过很多问题。
例如:Python中为什么没有Web服务器的概念,直接把Web框架在服务器上启动起来,Web应用程序就可以运行?
1.1.Web的概念
World Wide Web的缩写,中文意思为全球广域网,也被称万维网,简称取了英文全称中最后1个单词-Web,人类通过Web服务可实现各种信息的共享。
万维网(Web)是建立在互联网上的一种网络服务,这种服务的表示形式是:
- 用户在浏览器输入1个URL(Uniform Resource locator)统一资源定义符
- 经过网络传输从1个网站上从获取到1个Web资源,经过浏览器解析呈现到用户眼前就是1个漂亮的网站。
1.2.Web资源
Web资源划分为静态Web资源和动态Web资源。
- 静态Web资源:有HTML、JavaScript、CSS。
- 动态Web资源:能和数据库交互产生不断变化数据的程序处理逻辑,有Servlet/JSP、ASP、PHP
1.3.JavaWeb
用于开发静态资源的技术称为前端技术。
在Java中用于开发动态Web资源的技术称为JavaWeb
1.4.Web应用程序
Web应用程序运行在服务器上,架构为B/S,用户可以通过浏览器访问的这个Web应用程序,称为Web应用程序。
1个Web应用程序的代码结构由静态Web资源和动态Web资源构成,例如:
- HTML.CSS、JavaScript
- JSP、Servlet
- Java程序
- jar包
- 配置文件
Web应用程序工作流程如下:
二、Tomcat
Tomcat可以帮助我们快速构建出1个完整的Web应用程序,并完成静态Web资源和动态Web资源的统一管理。
Tomcat是一个由Apache基金组织开发的免费开源Web服务器软件,Tomcat这款软件可以对静态Web资源和动态Web资源进行统一管理。
我们遵循TocatWeb服务器软件中定义的规范,通过Tomcat+Servlet可以构建出动态Web资源(Java程序),通过HTML、CSS、JavaScript构建出静态Web资源,把构建好的静态Web资源和动态Web资源,部署到Tomcat软件指定的目录下,再在1台外网服务器上启动Tomcat软件,即可对外提供Web服务。
经过以上流程构就可以建出了1个完整的Web应用程序,实现人类信息共享交互的目的。
浏览器访问: http://localhost:8080
* 现象:黑窗口一闪而过 * 原因:Tomcat是java编写,启动时依赖JAVA_HOME环境变量 * 解决:正确配置JAVA_HOME环境变量和PATH路径
方式1: 安装目录/bin/shutdown.bat双击文件即可
方式2: 直接关闭tomcat的运行窗口
3.Tomcat内存调优
内存方式的设置是在 catalina.sh 中,调整一下 JAVA_OPTS 变量即可,因为后面的启 动参数会把 JAVA_OPTS 作为 JVM 的启动参数来处理。
具体设置如下: JAVA_OPTS=“$JAVA_OPTS -Xmx1024m -Xms1024m” 其各项参数如下: -Xmx3550m:设置 JVM 最大可用内存为 1024M。 -Xms3550m:设置 JVM 初始内存为 1024m。此值可以设置与-Xmx 相同,以避免每次 垃圾回收完成后 JVM 重新分配内存。
2.Nginx反向代理
nginx.exe :启动Nginx服务
nginx.exe -v :查看nginx版本 nginx.exe -t :检查nginx配置文件正确 nginx.exe -s reload :重新加载nginx的配置文件(需要在nginx运行状态下执行) nginx.exe -s stop :停止nginx服务(需要在nginx运行状态下执行)
2.2.Nginx配置文件
主配置文件位置:conf/nginx.conf,整体上分为三部分: 全局块、events块、http块。这三块的分别配置什么样的信息呢?
职责 | |
---|---|
全局块 | 配置和nginx运行相关的全局配置 |
events块 | 配置和网络连接相关的配置 |
http块 |
代理: 给某个对象提供一个代理对象,并由代理对象控制原对象的引用
正向代理
# 0. 关闭目前linux下的所有tomcat, 然后使用两个窗口重新运行两个tomcat,分别监听8080和8081端口 nohup java -jar /usr/local/reggie-web-manage-1.0-SNAPSHOT.jar --server.port=8080 > /usr/local/manage1.log & nohup java -jar /usr/local/reggie-web-manage-1.0-SNAPSHOT.jar --server.port=8081 > /usr/local/manage2.log & # 放行防火墙 firewall-cmd --zone=public --add-port=8080/tcp --permanent firewall-cmd --zone=public --add-port=8081/tcp --permanent firewall-cmd --reload # 1. 修改nginx的配置文件 vim /usr/local/nginx/conf/nginx.conf server { listen 80; server_name localhost; location / { # 声明反向代理 proxy_pass http://localhost:8080; } } # 2. 重新加载配置 /usr/local/nginx/sbin/nginx -s reload # 3. 通过浏览器访问nginx测试效果
负载均衡(Load Balance, LB)意思就是将一份负载分摊到多个操作单元上进行执行
配置
# 1. 修改nginx的配置文件 vim /usr/local/nginx/conf/nginx.conf # 声明负载均衡 upstream tomcatserver{ server localhost:8080 weight=2; server localhost:8081 weight=1; } server { listen 80; server_name localhost; location / { # 声明反向代理 proxy_pass http://tomcatserver; } } # 2. 重新加载nginx配置 /usr/local/nginx/sbin/nginx -s reload # 3. 通过浏览器多次访问nginx测试效果
名称 | 说明 | 特点 |
---|---|---|
轮询 | 默认方式 | |
weight | 权重方式 | 根据权重分发请求,权重大的分配到请求的概率大 |
ip_hash | 依据ip分配方式 | 根据客户端请求的IP地址计算hash值, 根据hash值来分发请求, 同一个IP发起的请求, 会发转发到同一个服务器上 |
least_conn | 依据最少连接方式 | 哪个服务器当前处理的连接少, 请求优先转发到这台服务器 |
url_hash | 依据url分配方式 | 根据客户端请求url的hash值,来分发请求, 同一个url请求, 会发转发到同一个服务器上 |
fair | 依据响应时间方式 | 优先把请求分发给处理请求时间短的服务器 |
3.分布式session解决方案
3.1.Nginx ip_hash 策略
服务端使用 Nginx 代理,每个请求按访问 IP 的 hash 分配,这样来自同一 IP 固定访问一个后台服务器,避免了在服务器 A 创建 Session,第二次分发到服务器 B 的现象
3.2.Session 复制
Tomcat广播功能:任何一个服务器上的 Session 发生改变(增删改),该节点会把 这个 Session 的所有内容序列化,然后广播给所有其它节点。
3.3.共享 Session
Tomcat广播建议4台Tomcat之内,否则造成广播风暴;
服务端无状态话,将用户的 Session 等信息使用缓存中间件来统 一管理,保障分发到每一个服务器的响应结果都一致。
* 首先回顾下前端web工程的目录结构 |-myapp(前端工程) |-- css |-- js |-- img |-- index.html * 在JavaEE规范中,WEB项目存在一定的目录结构,具体结构如下: |-myapp(web工程) |--静态资源目录:(static) css、js、html、图片、视频 |--WEB-INF目录 (这下面的资源,无法直接通过浏览器访问) |--classes 程序的.class文件 |--lib 依赖的jar包存放的文件 |--web.xml web项目配置文件 |--index.jsp(index.html) 项目首页
学习如何利用idea开发一个Java项目,并把它部署到tomcat中运行
创建JavaEE企业级应用模块
在项目中创建HTML页面
将编写的项目部署到Tomcat服务器
本质:接口,一个类想要被tomcat正确识别,那么这个类就必须直接或间接的实现Servlet接口。
1.Servlet体系结构
* Servlet接口 这是Servlet的根接口,所有的Servlet都必须直接或间接的实现它 * |---GenericServlet抽象类 这是一个抽象类,它实现了Servlet接口中的大部分方法,只剩下了一个service方法等待我们实现 * |------HttpServlet抽象类 这是一个专门用来处理http请求的类,在这个类中可以轻松的对不同的请求类型进行处理
2.实现Servlet接口
package com.zhanggen.servlet; import javax.servlet.*; import java.io.IOException; import java.util.Date; //实现Servlet接口 //通过WEB-INF/web.xml配置文件配置路由 public class MyServlet implements Servlet { //声明1个成员变量用于保存当前servlet的配置信息 private ServletConfig servletConfig; @Override public void init(ServletConfig servletConfig) throws ServletException { //初始化当前servlet的配置信息 this.servletConfig = servletConfig; System.out.println("对象创建"); } @Override public ServletConfig getServletConfig() { //返回当前servlet的配置信息 return this.servletConfig; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("当前servlet的名称:" + this.getServletConfig().getServletName()); //通过设置http请求头信息解决乱码问题 servletResponse.setContentType("text/html;charset=utf-8"); servletResponse.getWriter().write("实现Servlet接口:" + new Date().toString()); } @Override public String getServletInfo() { return null; } @Override public void destroy() { System.out.println("对象销毁"); } }
-------------------------------
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <servlet> <servlet-name>myServlet</servlet-name> <servlet-class>com.zhanggen.servlet.MyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>myServlet</servlet-name> <url-pattern>/myServlet</url-pattern> </servlet-mapping> </web-app>
和以上实现Servlet接口创建servlet的方式相比,只需要在实现1个service方法即可。
4.继承HttpServlet实现类
和以上继承ServletRequest和ServletResponse两个请求和响应的参数无需再向下转型。