一 WEB技术
1.1 HTTP协议和B/S 结构
1.2 前端三大核心技术
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>首页 </title></head><body><h1>小俞,要努力啊啊啊啊!!加油!!! </h1></body></html>
1.2.2 CSS(Cascading Style Sheets)层叠样式表
二 WEB框架
2.1 web资源和访问
2.2 后台应用架构
- 传统架构(单机系统),一个项目一个工程:比如商品、订单、支付、库存、登录、注册等等,统 一部署,一个进程;
- all in one的架构方式,把所有的功能单元放在一个应用里。然后把整个应用部署到一台服务器上。如果负载能力不行,将整个应用进行水平复制,进行扩展,然后通过负载均衡实现访问。
- Java实现:JSP、Servlet,打包成一个jar、war部署
- 易于开发和测试:也十分方便部署;当需要扩展时,只需要将war复制多份,然后放到多个服务器上,再做个负载均衡就可以了。
- 如果某个功能模块出问题,有可能全站不可访问,修改Bug后、某模块功能修改或升级后,需要停掉整个服务,重新整体重新打包、部署这个应用war包,功能模块相互之间耦合度高,相互影响,不适合当今互联网业务功能的快速迭代。
- 特别是对于一个大型应用,我们不可能吧所有内容都放在一个应用里面,我们如何维护、如何分工合作都是问题。如果项目庞大,管理难度大
- web应用服务器:开源的tomcat、jetty、glassfish。商用的有weblogic、websphere、Jboss
2.2.2 微服务
- 属于SOA(Service Oriented Architecture)的子集
- 微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底去掉耦合,每一 个微服务提供单个业务功能,一个服务只做一件事。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等
- 从技术角度讲就是一种小而独立的处理过程,类似与进程的概念,能够自行单独启动或销毁
- 微服务架构(分布式系统),各个模块/服务,各自独立出来,"让专业的人干专业的事",独立部署。分布式系统中,不同的服务可以使用各自独立的数据库。
- 服务之间采用轻量级的通信机制(通常是基于HTTP的RESTful API)。
- 微服务设计的思想改变了原有的企业研发团队组织架构。传统的研发组织架构是水平架构,前端、后端、DBA、测试分别有自己对应的团队,属于水平团队组织架构。而微服务的设计思想对团队的划分有着一定的影响,使得团队组织架构的划分更倾向于垂直架构,比如用户业务是一个团队来负责,支付业务是一个团队来负责。但实际上在企业中并不会把团队组织架构拆分得这么绝对,垂直架构只是一种理想的架构
- 微服务的实现框架有多种,不同的应用架构,部署方式也有不同
- 每个服务足够内聚,足够小,代码容易理解。这样能聚焦一个只当的业务功能或业务需求。
- 开发简单、开发效率提高,一个服务可能就是专业的只干一件事,微服务能够被小团队单独开发,这个小团队可以是2到5人的开发人员组成
- 微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的。
- 微服务能使用不同的语言开发
- 易于和第三方集成,微服务运行容易且灵活的方式集成自动部署,通过持续集成工具,如:Jenkins、Hudson、Bamboo
- 微服务易于被一个开发人员理解、修改和维护,这样小团队能够更关注自己的工作成果,无需通过合作才能体现价值
- 微服务允许你利用融合最新技术。微服务只是业务逻辑的代码,不会和HTML/CSS或其他界面组件混合,即前后端分离
- 每个微服务都有自己的存储能力,可以有自己的数据库,也可以有统一数据库
- 微服务把原有的一个项目拆分成多个独立工程,增加了开发、测试、运维、监控等的复杂度
- 微服务架构需要保证不同服务之间的数据一致性,引入了分布式事务和异步补偿机制,为设计和开发带来一定挑战
- 开发人员和运维需要处理分布式系统的复杂性,需要更强的技术能力
- 微服务适用于复杂的大系统,对于小型应用使用微服务,进行盲目的拆分只会增加其维护和开发成本
- 阿里开源贡献给了ASF,目前已经是Apache的顶级项目
- 一款高性能的Java RPC服务框架,微服务生态体系中的一个重要组件
- 将单体程序分解成多个功能服务模块,模块间使用Dubbo框架提供的高性能RPC通信
- 内部协调使用Zookeeper,实现服务注册、服务发现和服务治理
- 一个完整的微服务解决方案,相当于Dubbo的超集
- 微服务框架,将单体应用拆分为粒度更小的单一功能服务
- 基于HTTP协议的REST(Representational State Transfer 表述性状态转移)风格实现模块间通信
三 tomcat的功能介绍
3.1 安装 Tomcat
[root@tomcat ~]# yum install java-1.8.0-openjdk.x86_64 -y
拖入 apache-tomcat-9.0.93.tar.gz
//node1和node2相同配置;
寻找需要下载的文件
[root@tomcat-node1 ~]# dnf install java-1.8.0-openjdk.x86_64 -y
[root@tomcat-node1 ~]# tar zxf apache-tomcat-9.0.93.tar.gz -C /usr/local/
[root@tomcat-node1 ~]# ln -s /usr/local/apache-tomcat-9.0.93/ /usr/local/tomcat
[root@tomcat-node1 ~]# /usr/local/tomcat/bin/startup.sh
查看端口:
[root@tomcat-node1 bin]# netstat -anltupe | grep java
测试:
3.2 tomcat的文件结构和组成
目录 说明-------------------------------------------------------bin 服务启动、停止等相关程序和文件conf 配置文件lib 库目录logs 日志目录webapps 应用程序,应用部署目录,相当于 nginx 的默认发布目录work jsp 编译后的结果文件,建议提前预热访问
[root@tomcat ~]# tar zxf apache-tomcat-9.0.93.tar.gz -C /usr/local/[root@tomcat ~]# ls /usr/local/tomcat/bin conf lib logs README.md RUNNING.txtwebappsBUILDING.txt CONTRIBUTING.md LICENSE NOTICE RELEASE-NOTES temp work
实验:
[root@tomcat-node1 ~]# vim /usr/local/tomcat/conf/tomcat.conf
JAVA_HOME=/etc/alternatives/jre_openjdk
[root@tomcat-node1 ~]# useradd -s /sbin/nologin -M tomcat
[root@tomcat-node1 ~]# chown -R tomcat.tomcat /usr/local/apache-tomcat-9.0.93/
[root@tomcat-node1 ~]# chown -R tomcat.tomcat /usr/local/tomcat
[root@tomcat-node1 ~]# vim /lib/systemd/system/tomcat.service
[Unit]
Description=Tomcat
#After=syslog.target network.target remote-fs.target nss-lookup.target
After=syslog.target network.target
[Service]
Type=forking
EnvironmentFile=/usr/local/tomcat/conf/tomcat.conf
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
PrivateTmp=true
User=tomcat
Group=tomcat
[Install]
WantedBy=multi-user.target
测试:(无报错)
tomcat-node1:
[root@tomcat-node1 ~]# systemctl daemon-reload
[root@tomcat-node1 ~]# systemctl enable --now tomcat
tomcat-node2:
[root@tomcat-node2 ~]# systemctl daemon-reload
[root@tomcat-node2 ~]# systemctl enable --now tomcat
四 结合反向代理实现tomcat部署
4.1 常见部署方式介绍
- standalone模式,Tomcat单独运行,直接接受用户的请求,不推荐。
- 反向代理,单机运行,提供了一个Nginx作为反向代理,可以做到静态由nginx提供响应,动态jsp代理给Tomcat
- LNMT:Linux + Nginx + MySQL + Tomcat
- LAMT:Linux + Apache(Httpd)+ MySQL + Tomcat
- 前置一台Nginx,给多台Tomcat实例做反向代理和负载均衡调度,Tomcat上部署的纯动态页面更
- 适合
- LNMT:Linux + Nginx + MySQL + Tomcat
- 多级代理
- LNNMT:Linux + Nginx + Nginx + MySQL + Tomcat
实验:
将text.jsp拖入,其内容如下;
[root@tomcat-node1 ~]# cat test.jsp
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> ID " + session.getId()+"<br>");
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("<b>Session list</b>");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+"<br>");
System.out.println( name + " = " + value);
}
%>
<form action="test.jsp" method="POST">
name:<input type=text size=20 name="dataName">
<br>
key:<input type=text size=20 name="dataValue">
<br>
<input type=submit>
</form>
</body>
</html>
[root@tomcat-node1 ~]# cp test.jsp /usr/local/tomcat/webapps/ROOT/
//将其拷贝到20
[root@tomcat-node1 ~]# scp test.jsp root@172.25.254.20:/usr/local/tomcat/webapps/ROOT/
测试:
4.2 利用 nginx 反向代理实现
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conflocation ~ \.jsp$ {proxy_pass http://172.25.254.10:8080;}
测试:
lee.timinglee.org/test.jsp
实验:(在nginx中进行操作(代理))
[root@nginx-node1 conf]# cd /usr/local/nginx/conf.d/
[root@nginx-node1 conf.d]# vim vhost.conf
[root@nginx-node1 conf.d]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx-node1 conf.d]# nginx -s reload
测试:
4.3 实现tomcat中的负载均衡
- 无状态:指的是服务器端无法知道2次请求之间的联系,即使是前后2次请求来自同一个浏览器,也没有任何数据能够判断出是同一个浏览器的请求。后来可以通过cookie、session机制来判断。
- 浏览器端第一次HTTP请求服务器端时,在服务器端使用session这种技术,就可以在服务器端产生一个随机值即SessionID发给浏览器端,浏览器端收到后会保持这个SessionID在Cookie当中,这个Cookie值一般不能持久存储,浏览器关闭就消失。浏览器在每一次提交HTTP请求的时候会把这个SessionID传给服务器端,服务器端就可以通过比对知道是谁了
- Session通常会保存在服务器端内存中,如果没有持久化,则易丢失
- Session会定时过期。过期后浏览器如果再访问,服务端发现没有此ID,将给浏览器端重新发新的SessionID
- 有连接:是因为它基于TCP协议,是面向连接的,需要3次握手、4次断开。
- 短连接:Http 1.1之前,都是一个请求一个连接,而Tcp的连接创建销毁成本高,对服务器有很大的影响。所以,自Http 1.1开始,支持keep-alive,默认也开启,一个连接打开后,会保持一段时间(可设置),浏览器再访问该服务器就使用这个Tcp连接,减轻了服务器压力,提高了效率。
实验:
[root@nginx-node1 conf]# cd /usr/local/nginx/conf.d/
[root@nginx-node1 conf.d]# vim vhost.conf
[root@nginx-node1 conf.d]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx-node1 conf.d]# nginx -s reload
当我们编译时,只写这两个,会导致我们访问的时候,访问地址刷新一次就会换一次,会在10和20中循环;故我们需要添加会话保持:
ip_bash;#hash $cookie_JSESSIONID;
测试:(反复刷新,访问地址始终不发生变化)
五 Memcached
5.1 Memcached简介
5.2 memcached的安装与启动
[root@tomcat ~]# yum install memcached -y[root@tomcat ~]# vim /etc/sysconfig/memcachedPORT="11211"USER="memcached"MAXCONN="1024"CACHESIZE="64"OPTIONS="-l 0.0.0.0,::1"[root@tomcat ~]# systemctl enable --now memcached[root@tomcat ~]# netstat -antlupe | grep memcachetcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN980 97815 34711/memcached
实验:两台都装
[root@tomcat-node1 ~]# dnf install memcached -y
[root@tomcat-node1 ~]# vim /etc/sysconfig/memcached
[root@tomcat-node1 ~]# systemctl start memcached.service
测试:
[root@tomcat-node1 ~]# netstat -autlupe | grep memcached
5.3 memcached 操作命令
- set
- add
- replace
- get
- delete
# 前三个命令是用于操作存储在 memcached 中的键值对的标准修改命令 , 都使用如下所示的语法:command <key> <flags> <expiration time> <bytes><value># 参数说明如下:command set/add/replacekey key 用于查找缓存值flags 可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息expiration time 在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)bytes 在缓存中存储的字节数value 存储的值(始终位于第二行)# 增加 key ,过期时间为秒, bytes 为存储数据的字节数add key flags exptime bytes
示例:
[root@tomcat ~]# telnet localhost 11211Trying ::1...Connected to localhost.Escape character is '^]'.# 增加add leekey 0 60 4 #0 是否压缩 60 过期时间 4 字长testSTOREDadd leekey1 0 60 3leeSTORED# 查看get leekeyVALUE leekey 0 4testget leekey1VALUE leekey1 0 3lee# 改set leekey 0 60 5test1STOREDget leekeyVALUE leekey 0 5test1ENDadd leekey1 0 60 4test# 删除delete leekeyDELETEDget leekeyEND
实验:
[root@tomcat-node1 ~]# dnf install telnet -y
[root@tomcat-node1 ~]# telnet 172.25.254.10 memcache
测试:(自己练)
六 session 共享服务器
6.1 msm 介绍
支持Tomcat的 6.x、7.x、8.x、9.x
- Tomcat的Session管理类,Tomcat版本不同
- memcached-session-manager-2.3.2.jar
- memcached-session-manager-tc9-2.3.2.jar
- Session数据的序列化、反序列化类
- 官方推荐kyro
- 在webapp中WEB-INF/lib/下
- 驱动类
- memcached(spymemcached.jar)
- Redis(jedis.jar)
6.2 安装
kryo-3.0.3.jarasm-5.2.jarobjenesis-2.6.jarreflectasm-1.11.9.jarminlog-1.3.1.jarkryo-serializers-0.45.jarmsm-kryo-serializer-2.3.2.jarmemcached-session-manager-tc9-2.3.2.jarspymemcached-2.12.3.jarmemcached-session-manager-2.3.2.jar
[root@tomcat-node1 ~]# ls
[root@tomcat-node1 ~]# cd jar/
[root@tomcat-node1 jar]# cp *.jar /usr/local/tomcat/lib/
[root@tomcat-node1 jar]# cd /usr/local/tomcat/lib/
[root@tomcat-node1 lib]# ll
6.3 配置过程
[root@tomcat-1 ~]# vim /usr/local/tomcat/conf/context.xml@@@@ 内容省略 @@@@<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"memcachedNodes="n1:172.25.254.10:11211,n2:172.25.254.20:11211"failoverNodes="n1"requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"/>[root@tomcat-2 tomcat]# vim /usr/local/tomcat/conf/context.xml@@@@ 内容省略 @@@@<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"memcachedNodes="n1:172.25.254.10:11211,n2:172.25.254.20:11211"failoverNodes="n2"requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"/>
修改nginx配置
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.confupstream tomcat {hash $cookie_JSESSIONID;server 172.25.254.10:8080;server 172.25.254.20:8080;}server {listen 80;server_name lee.timinglee.org;root /webdataw/nginx/timinglee.org/lee;access_log /var/log/nginx/access.log;error_log /var/log/nginx/error.log;try_files $uri $uri.html $uri/index.html /error/default.html;location ~ \.jsp$ {proxy_pass http://tomcat;}}
实验:
[root@tomcat-node1 lib]# vim /usr/local/tomcat/conf/context.xml
[root@tomcat-node1 lib]# systemctl restart tomcat.service
10中:
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="m1:172.25.254.10:11211,m2:172.25.254.20:11211"
failoverNodes="m1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
20中;<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="m1:172.25.254.10:11211,m2:172.25.254.20:11211"
failoverNodes="m2"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
10中:
20中:
测试:(连接并刷新,输入的值不在消失,并且在n1被停止后继续提交信息,可以读取到之前的会话信息)
[root@tomcat-node1 ~]# systemctl stop tomcat