应届生面试要点总结(13)web开发相关

servlet是java编写的服务器端程序,使用java servlet api,当客户机发送请求到服务器时,服务器可以将请求发送给servlet,并让servlet建立起服务器返回给客户机的响应。当web服务器或者客户机第一次请求服务时,可以自动装入servlet,装入后servlet继续运行直到其他客户机发出请求。

servlet生命周期:初始化阶段:调用init()方法;响应客户机请求:调用service();终止,调用destory()。

初始化阶段:在下列时刻servlet容器装载servlet:servlet容器启动时,自动装载某些servlet;在servlet容器启动后,客户向servlet发送请求;servlet类文件被更新以后,重新装载servlet。servlet被装载以后,servlet容器创建一个servlet并调用servlet的init方法。在servlet生命周期内,init()方法只被调用一次。工作原理:客户端发起一个请求,servlet调用service()方法时请求响应,service对请求的方法进行匹配,选择调用dopost或doget等这些方法,然后进入到对应的方法中调用逻辑层的方法,实现对客户的响应。

客户响应请求:对于用户到servlet的请求,servlet容器会创建特定于该请求的servletrequest和servletresponse对象,然后调用servlet的service方法,service方法从servletrequest对象向客户返回响应消息。

终止:当web应用终止或者servlet容器终止或servlet容器重新装载servlet新实例时,servlet容器会调用servlet对象的destory方法,在destory方法中释放占用的资源。

以下方法都由servlet容器调用:

构造函数:只有第一次请求servlet时,创建servlet实例,调用构造器,这说明servlet是单例的,所以有线程安全问题,只被调用一次。

init:只被调用一次,在创建好实例后,立即被调用,用来初始化servlet。

service:被多次调用,每次请求都会调用service,实际响应请求。

destroy:只被调用一次,在当前servlet所在的web应用被卸载前调用,用于释放当前servlet所占的资源。

tomcat就是servlet容器,servlet容器为javaweb应用提供运行时环境,它复制servlet和jsp的生命周期,以及管理他们的共享数据。

jsp内置对象。request: httpservletrequest用户端的请求,此请求会包含来自于get或post请求的参数。response:httpservletresponse网页传回用户端的响应。pageContext:网页的属性,页面上下文。session:与请求有关的会话,是httpsession对象。application:代表当前web应用,是servletcontext对象。out:jspwriter对象,调用out.print()可以把字符串打印到浏览器。config:当前jsp对应的servlet的servletconfig对象,几乎不用。page:只能调用object方法,几乎不用,指向当前jsp对应的servlet对象的引用。exception:网页错误,在声明了page指令的iserrorpage="true"时才可用。

httpsession生命周期:若当前jsp是客户端访问的当前web应用的第一个资源,且page指定的session=false,则服务器不会为jsp创建session对象。若当前jsp不是客户端访问的当前web应用的第一个资源,且其他页面已经创建了其他httpsession对象,则会返回一个和当前会话相关的httpsession对象,不会创建一个新对象。session=false,当前jsp页面禁用session隐含变量,但可以使用其他的显式的httpsession对象。对于servlet,若servlet是客户端访问的第一个web资源,只有调用request.getSession()或除了前面的情况,只要访问jsp,则要创建session对象。销毁:直接调用httpsession的invalidate方法,该方法使httpsession失效;当前web应用被卸载;超出httpsession的过期时间。

jsp动作:6个。jsp:include在页面被请求时,引入一个文件。jsp:useBean寻找或实例化一个javaBean。jsp:setProperty设置javaBean的属性。jsp:getProperty输出某个javaBean属性。jsp:forward把请求转到一个新页面。jsp:plugin根据浏览器类型为java插件生成object或embed标配。

jsp种动态include与静态include区别?答案:动态include用jsp:include动作实现,它总会检查所包含文件中的变化,适用于包含动态页面;静态include用include伪代码实现,不会检查所包含文件的变化,适用于静态页面。

jsp可以放在web应用程序除了web-inf中。每个jsp页面在第一次被访问时,jsp引擎将他翻译成一个servlet源程序,接着再把这个servlet源程序编译成servlet的class文件,然后再由web容器(servlet引擎)像调用普通servlet程序一样来装载和解释这个由jsp页面翻译成的servlet程序。

多个请求映射到同一个jsp页面:这几个请求的名字都为xxx.do,所有以.do结尾的都映射到同一个servlet。用request获得path即/xxx.do。去掉后面的.do和前面的“/”,得到方法名即xxx。利用反射调用相关方法。

java中文乱码问题:在jsp页面上输入中文,提交页面后不出现乱码pageEncoding, charset的编码一致,且都支持中文,建议为utf-8,还需保留浏览器显示的字符编码也和请求的jsp编码一样。获取参数中的中文,默认参数在传输过程中使用ISO-8859-1。对于post请求:值需要在获取请求之前调用request.setCharacterEncoding("utf-8");对于get请求,String username = new String(val.getbytes(iso-8859-1), "utf-8"),先用8859解码,再用utf-8编码。

url存中文:先对中文进行编码,tomcat默认解码为iso8859-1,这样会出现乱码,我们可以用iso8859-1编码,再用指定的码表解码(post和get都可以)。对于post,可以使用request的setCharacterEncoding方法设置指定的解码表。

servlet页面间传递对象的方法有几种?用request, session, application. cookie等方法实现页面间对象传递。一个servlet可以有多个servlet-mapping对其进行映射。

与开发servlet不同,filter接口并没有相应的类可继承,要开发过滤器,只能实现filter接口。目的:调用目标资源前让一段代码执行,是否允许用户调用目标资源,调用目标资源后,让一段代码执行。

filter过滤器filter的基本功能是对servlet容器调用servlet的过程进行拦截,从而在servlet进行相应处理的前后实现一些特殊的功能。filter程序实现了一个filter接口的java类,他由servlet容器进行调用和执行。init()方法类似于servlet的init方法,创建filter对象后,立即被调用,且只被调用一次。filter对象在servlet容器加载当前web应用程序时就会被创建。filter实例是单例的。doFilter方法,逻辑代码写在这里面,每次拦截器都会调用的方法。有三个参数,servletrequest, servletresponse,filterchain(filter链,多个filter可以构成一个filter链,只有一个方法dofilter(request, response),把请求传递给下一个filter,若当前filter是链的最后一个,把请求传递给servlet)。若有多个filter满足要求,则拦截顺序与web.xml中的filter-mapping的配置顺序有关。destroy:释放当前filter所占用的资源,filter销毁前调用,且只调用一次。

filter的dispatcher节点(表明拦截哪种方式的页面)默认为request,还可以的取值有forward, error, include。request直接发起get或post请求,当用户直接访问页面时,web容器会调用过滤器。include若目标资源是通过requestdispatcher的include方法访问,则该过滤器会被调用。

forward:<jsp:forward page=...>,requestdispatcher.forward,通过page指令的errorpage转发页面。error:若目标资源是通过声明式异常处理机制调用时,则该过滤器会被调用。dispatcher节点可以有多个。

filter的应用:禁用浏览器的缓存,实现url级别的权限认证。字符编码过滤器,统一全站的字符编码。若没有过滤器则在每个请求页面中都要写request.setcharacterencoding,有了filter,对于所有请求都经过filter,只需重写一次。检测用户是否登陆的filter。

监听器:专门用于对其他对象身上发生的事件或状态的改变进行监听或相应处理的对象。当被监视的对象发生情况时,立即采取相应的行动。

servlet监听器:一种特殊的类,用于监听servletcontext, httpsession, servletrequest等域对象的创建与销毁的事情,以及监听这些对象中属性发生修改的事件。servletcontextlistener最为常用,监听servletcontext对象创建或销毁的servlet监听器,可以在当前web应用被加载时对当前web应用的相关资源进行初始化,比如:创建数据库连接池。httpsessionlistener:sessioncreate在session被创建后调用,sessiondestroy在session销毁前调用。

load-on-startup:配置在servlet节点中,用来指定servlet实例被创建的时机。若为负数,则在第一次被请求时创建,若为0或正数,则在当前web应用被servlet容器加载时创建实例,且数值越小越早被创建。

servletconfig:init函数的参数,它封装了servlet的配置信息,并且可以获得servletcontext对象。

servlet引擎为每个web应用创建一个servletcontext对象,一个web应用程序中所有servlet都共享一个servletcontext对象,他对应一个web应用。

servletrequest里封装了所有有关请求的信息,但是要看get还是post方式,必须用httpservletrequest的getmethod方法。

jsp对比servlet:jsp是servlet技术的扩展,本质上是servlet的简单方式,jsp编译后是“类servlet”。主要不同在于:servlet的应用逻辑在java中,并且完全从表示层的html分离出来。jsp是java和html可以组合为一个扩展名为.jsp的文件。jsp侧重视图,sevlet侧重控制逻辑。

HTTP本身是一个无状态的连接协议,为了支持客户端与服务器之间的交互,需要通过不同的技术为交互存储状态,而这些不同的技术就是Cookie和Session。web服务器不能识别出哪些请求是同一个浏览器发出的,浏览器的每一次请求都是完全独立的。cookie放在浏览器端,浏览器第一次访问服务器时,没有cookie,然后服务器给浏览器一个cookie,以后每次浏览器访问服务器都带上这个cookie。默认情况下cookie是会话级别的,存储在浏览器内存中,用户退出浏览器之后被删除,若希望浏览器将cookie存储在磁盘的,则要使用maxage,并给以一个秒为时间单位,表示cookie的存活时间。

cookie作用范围:可以作用当前目录和当前目录的子目录,但不能作用与当前目录的上一级。

cookie保持http状态信息的方案,会话跟踪。session在服务端保持http状态信息,浏览器不关始终都是一个session,关闭浏览器只是使浏览器内存中的session cookie失效,不使服务器端的session失效。

当浏览器第一次访问服务器时,没有cookie,服务器也就得不到jSession_id,然后服务器创建一个session对象,并返回一个jSession_id给浏览器,通过cookie返回,下次浏览器再访问服务器时,就带上cookie(其中又jSessin_id),服务器就能找到对应的session对象。jSession_id可以通过cookie传输(默认),也可以通过url传送。

当程序需要为某个客户端请求创建session时,服务器首先检查这个请求是否包含一个session标识,即jSession_id,如果包含,则说明以前已经为此客户创建过jSession_id,服务器就按照这个jSession_id检索出来(若检索不到,可能会新建一个,这种情况下可能会出现在服务器已经删除了该用户的session对象,但用户人为请求的url上附加了jSession_id参数)如果不包含则创建一个session,并生成id,这个id在本次响应中返回客户端。

session可以放在服务器内存、文件或数据库中。

如何实现session共享:通过组播方式进行集群间共享,当一台机器的session变更后会将变更的数据以组播的方式分发给集群中所有其他节点。利用nfs等共享存储来共享session,用一台nfs服务器或数据库来存放session,缺点:nfs down掉。利用memcached或redis来共享,所有web服务器都把session写入memcache或redis,也从中来取。优点:网络开销小,几乎无io;缺点:受限于memcache容量。memcache本来就是分布式。

应用服务器:tomcat,支持j2ee,免费,支持servlet、jsp。jboss:开源应用服务器。weblogic、websphere:业内第一的appserver。apache:全球应用最广泛的http服务器,但只支持静态网页,比如asp、php等动态网页不支持。

j2ee多层解耦性好,维护扩展方便。至少3层:表现层、业务逻辑层、持久层。

memcache:是高性能分布式缓存服务器,本质是一个内存key-value数据库,但不支持数据持久化,服务器关闭后,数据全丢失。只支持key-value结构。

redis:将大部分数据放在内存中,支持的数据类型有:字符串,hash表,链表,集合,有序集合以及基于这些数据类型的相关操作。redis内部使用一个redisobject对象来表示所有key和value。

区别:redis中并不是所有数据一直存在内存中,这是和memcache相比最大的一个区别。redis不仅仅支持简单的key-value类型数据,同时还支持字符串、hash表、集合、有序集合。redis支持数据备份,即master-slave模式备份。redis支持数据的持久化,可以将内存中的数据保存在磁盘上,重启的时候可以再次加载进内存使用。memcache服务器关闭后,数据丢失。memcache服务器挂掉后,数据不可恢复,redis数据丢失后可以通过AOF恢复(灾难恢复)。

web service:是一种跨编程语言和跨操作系统的远程调用技术,就是说服务器采用java编写,客户端程序可用其他语言编写,可不同操作系统。所谓远程调用,就是计算机a的一个程序可以调用另一台计算机上的一个对象的方法。从表层看,web service就是一个应用程序向外界暴露出一个能通过web进行调用的api;从深层看,它定义了应用程序如何在web上实现互操作性,是一套标准。

xml+xsd:web service采用http传输协议,采用xml格式封装数据(xml中说明了调用远程服务对象的哪个方法,传参是什么,以及返回结果是什么)。xml易建立、易分析、与平台无关。xsd:xml schema:定义了一套标准的数据类型,当你用某种语言来构造一个web service时,为了符合web service标准,所有使用的数据类型必须被转化为xsd类型。soap协议=http协议+xml数据格式。wsdl:web service客户端调用一个服务,首先要知道这个服务在哪,以及有什么方法可调用,所以服务器通过一个wsdl文件说明自家有什么服务可对外调用,是什么(有什么方法,参数)。wsdl就是基于xml,用于描述web service及其函数,参数,返回值。

xml解析技术:dom必须在解析之前把整个文档装入内存,处理大型文件时性能低,适合xml随机访问。sax:事件驱动,顺序读取xml文件,不需要一次全部载入整个文件。当遇到文件开头,文档结束或标签开头或标签结束时,会触发一个事件,用户通过在其回调事件中写入处理代码来处理xml文件,适合顺序访问。digester将xml转为javabean。

nginx:可以根据客户端的ip进行负载均衡,在upstream里设置ip_path,负载均衡五种配置:

轮询(默认),每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

指定权重,指定轮询几率。权重越大,轮询几率越大,用于后端服务器性能不均的情况。

ip绑定ip_path,每个请求按访问ip的哈希结果分配,这样每个客户固定访问一个服务器,可以解决session问题。

fair(第三方)按后端服务器响应时间来分配请求,相应时间短的优先分配。

url_hash按访问结果来分配请求,使每个url定位到同一个后端服务器。后端服务器为缓存时比较有效。

get, post, head, delete, put, options, trace, connect

get和post:get提交的数据在地址栏,不安全,对大数据不行(地址栏有限),获取查询资源。post提交的信息不显示在地址栏,安全,对大数据可以,更改信息。

一个url对象,其构造函数new URL("String s"),比如new URL("http://www.baidu.com"),该字符串对应的ip为202.208.33.94,判断url对象是否相等:若两个主机名可以解析同一个ip地址,则认为两个主机相同,即url对象相同;若有一个主机名无法解析,但两个主机名相等( 不区分大小写),或者两个主机名都是null,则也认为这两个主机相等。

forward和redirect:forward是服务器请求资源,服务器直接访问目标地址的url,把url的相应内容读取出来,然后把这些内容发送给浏览器,浏览器根本不知道服务器发送的内容是从哪来的,所以他的的地址栏还是原来的地址。redirect服务器根据逻辑发送一个状态码,告诉浏览器重新去请求实现访问的那个地址,一般来说,浏览器会用刚才请求的所有参数重新请求,所有session,request参数都可以获取。地址栏显示的是新的url。用redirect等于客户端发向服务器发送两次request,同时接受两次response。

forward转发页面和转发到的页面可以共享request数据,redirect不能共享数据。forward只能在同一个web应用程序之间转发请求,redirect不仅可以重定向到当前应用程序的其他资源,还可以重定向到同一个站点上的其他应用程序,甚至可以使用绝对url定向到其他站点资源。forward的/表示当前web应用根目录,redirect的/代表当前web站点的根目录。

集群:伸缩性:系统适应性不断增长用户的能力。高可用性:避免单一服务器的单点失效。负载均衡:把请求发送给不同服务器。失效转移:当一个节点失效后通过选择集群中的另一个节点处理会继续而不会终止。

httpsession失效转移,用来保证某台服务器失效以后,会话状态不会丢失,为支持会话转移,web服务器在一定的时候把会话对象备份到其他地方,以放丢失。如jdbc数据库,其他服务器。

mybatis原理

加载配置:配置来源于两个地方,一是配置文件,一是Java代码的注解,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。

SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。

结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回。

tomcat体系架构,请求处理流程

Tomca的心脏是两个组件:Connecter和Container。一个Container可以选择多个Connecter,多个Connector和一个Container就形成了一个Service。Service可以对外提供服务,而Server服务器控制整个Tomcat的生命周期。

Connector组件:一个Connector将在某个指定的端口上侦听客户请求,接收浏览器的发过来的 tcp 连接请求,创建一个 Request 和 Response 对象分别用于和请求端交换数据,然后会产生一个线程来处理这个请求并把产生的 Request 和 Response 对象传给处理Engine(Container中的一部分),从Engine出获得响应并返回客户。Connector 最重要的功能就是接收连接请求然后分配线程让 Container 来处理这个请求,所以这必然是多线程的,多线程的处理是 Connector 设计的核心。

Container组件:Container是容器的父接口,该容器的设计用的是典型的责任链的设计模式,它由四个自容器组件构成,分别是Engine、Host、Context、Wrapper。这四个组件是负责关系,存在包含关系。通常一个Servlet class对应一个Wrapper,如果有多个Servlet定义多个Wrapper,如果有多个Wrapper就要定义一个更高的Container,如Context。Context 还可以定义在父容器 Host 中,Host 不是必须的,但是要运行 war 程序,就必须要 Host,因为 war 中必有 web.xml 文件,这个文件的解析就需要 Host 了,如果要有多个 Host 就要定义一个 top 容器 Engine 了。而 Engine 没有父容器了,一个 Engine 代表一个完整的 Servlet 引擎。

https由两部分组成:http+ssl/tls,也就是在http上又加上了一层加密信息模块,服务端和客户端的信息都会通过tls加密,传输的数据都是加密后的数据。

https加密过程:

客户端发起https请求(用户在浏览器输入https地址,然后连接到server的443端口)。

服务端的配置(采用https协议的服务器必须要有一塔数字证书,可以自己制作,可以向组织申请,这套证书就是一对公钥和密钥)。

传输证书(这个证书就是公钥,包含了很多信息)。

客户端解析证书(由客户端tls完成,首先验证公钥是否有效,若发现异常,则弹出一个警示框,提示证书存在问题,若无问题,则生成一个随机值,目的是为了让服务端得到这个随机的值,以后客户端和服务端通信就可以通过这个随机值来加密了)。

传输加密信息(这里传输的是加密后的随机值,目的是让服务端得到这个随机值,以后客户端和服务端的通信就靠这个随机值来加密了)。

服务端加密信息(服务端用私钥解密后得到客户端传来的随机值,然后把内容通过该值进行对称加密。所谓对称加密就是,将信息和私钥通过某种算法混在一起,这样除非知道私钥,不然无法获取内容,正好两端都知道这个私钥,所以只要加密算法够强,密钥够复杂,数据就够安全)。

传输加密信息。

客户端解密信息,用随机数来解。

在客户端(浏览器)抓包抓到的是没加密的。

http:请求行:请求方法-url-协议/版本;请求头(键值对),空行,实体;

响应,协议-状态码-描述,响应头,空行,响应实体。

200 - 请求成功。301 - 资源(网页等)被永久转移到其它URL。404 - 请求的资源(网页等)不存在。500 - 内部服务器错误。

1**信息,服务器收到请求,需要请求者继续执行操作。2**成功,操作被成功接收并处理。3**重定向,需要进一步的操作以完成请求。4**客户端错误,请求包含语法错误或无法完成请求。5**服务器错误,服务器在处理请求的过程中发生了错误。

http请求过程:域名解析(baidu.com变为ip地址)。发起tcp三次握手,建立tcp连接,浏览器会以一个随机端口(1024-65535)向服务端的web程序80端口发起tcp的连接。这个请求(原始的http请求,经过原始的tcp/ip四层模型的封装),到达服务器端后,进入网卡,然后进入内核的协议栈(一层层剥开),然后到达web应用程序,最终建立了tcp/ip连接。建立tcp连接后发起http请求。服务器响应http请求,客户端得到html,服务器web应用程序收到http请求后,就开始处理请求,处理之后就返回给浏览器html文件。浏览器解析html,并请求html种的资源。浏览器渲染,呈现用户。

http2.0:二进制,分帧层,是HTTP 2.0性能增强的核心。HTTP 1.x在应用层以纯文本的形式进行通信,而HTTP 2.0将所有的传输信息分割为更小的消息和帧,并对它们采用二进制格式编码。这样,客户端和服务端都需要引入新的二进制编码和解码的机制。

正向代理:我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器能访问我不能访问的网站,于是我先连上服务器,告诉他我需要哪个无法访问的网站内容,代理服务器取回来给我。server不知道client。正向代理作用:访问原来无法访问的资源。可做缓存,加速访问资源。但代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息。客户端访问权限,上网进行验证。

反向代理:client不知道server,并不是url中请求的那个资源,而是不知道从什么地方来的。以代理服务器接收internet上的请求,然后将请求转发给内部网络服务器,并将从服务器上得到的结果返回给internet上请求的客户,此时代理服务器对外表现为一个服务器。保证内网安全;负载均衡;nginx通过proxy-pass-http配置代理站点,upstream实现负载均衡。

验证证书是否有效。验证证书是否在有效期内:证书中会包含证书的有效期的起始时间和结束时间。验证证书是否被吊销。被吊销的证书是无效的,验证吊销有两种:crl和ocsp。crl:吊销证书列表,证书被吊销后会记录在crl中,ca定期发布crl,应用程序可以依靠crl来验证证书是否被吊销。有两个缺点:可能会很大,下载很麻烦。有滞后性,就算证书被吊销了,应用页只能等到最新发布的crl才能直到。ocsp:在线证书检查协议,应用按照标准发送一个请求,对某张证书进行查询,之后服务器返回证书状态。ocsp可认为是即时的(实际实现中可能有延迟)。验证证书上是否有ca签名:每一级证书都是由上一级ca证书签发的,上级ca证书可能还有上级,最后会找打根证书,根证书即自签证书,自己签自己。以上三点只要有一个没通过,就是无效的,不该信任。

MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法)。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理。

MD5算法具有以下特点:压缩性:任意长度的数据,算出的MD5值长度都是固定的。容易计算:从原数据计算出MD5值很容易。抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。除了MD5以外,其中比较有名的还有sha-1、RIPEMD以及Haval等。

对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

秒杀场景设计

限流: 鉴于只有少部分用户能够秒杀成功,所以要限制大部分流量,只允许少部分流量进入服务后端。

削峰:对于秒杀系统瞬时会有大量用户涌入,所以在抢购一开始会有很高的瞬间峰值。高峰值流量是压垮系统很重要的原因,所以如何把瞬间的高流量变成一段时间平稳的流量也是设计秒杀系统很重要的思路。实现削峰的常用的方法有利用缓存和消息中间件等技术。

异步处理:秒杀系统是一个高并发系统,采用异步处理模式可以极大地提高系统并发量,其实异步处理就是削峰的一种实现方式。

内存缓存:秒杀系统最大的瓶颈一般都是数据库读写,由于数据库读写属于磁盘IO,性能很低,如果能够把部分数据或业务逻辑转移到内存缓存,效率会有极大地提升。

可拓展:当然如果我们想支持更多用户,更大的并发,最好就将系统设计成弹性可拓展的,如果流量来了,拓展机器就好了。像淘宝、京东等双十一活动时会增加大量机器应对交易高峰。

1、前端三板斧【扩容】【限流】【静态化】2、后端两条路【内存】+【排队】

简单抢红包

public class FirstThread {

public static void main(String[] args) {

Bao bao = new Bao(10, 5); // 10个红包,5个人抢

User user = new User(bao);

for (int i = 0; i < 10; i++) {

new Thread(user).start();

}

}

}

class User implements Runnable { // 每一个用户都是一个线程

private Bao bao;

public User(Bao bao) {

this.bao = bao;

}

@Override

public void run() {

double money = bao.getRandomMoney();

if(money == 0) {

System.out.println(Thread.currentThread().getName() + "不好意思,您手慢了!");

}else {

System.out.println(Thread.currentThread().getName() + "抢到 " + money + "元");

}

}

}

class Bao {

private double total; // 总钱数

private int totalVal; // 随机生成整数,将钱数化为整数

private int count; // 红包总数

public Bao(double total, int count) {

this.total = total;

this.count = count;

this.totalVal = (int)(total * 100);

}

public synchronized double getRandomMoney() {

int val;

if(count != 0 && totalVal / count == 1) { // 剩余钱数 0.04 4人的情况

val = 1;

totalVal = totalVal - val;

count--;

return val / 100.0;

}

if (count <= 0) {

val = 0;

} else if (count == 1) {

val = totalVal;

}else {

int temp; // 剩下的金额

while(true) {

val = new Random().nextInt(totalVal / count); // 随机生成当前金额的随机数 [0,totalVal/count),尽量平均一点

temp = totalVal - val;

if(temp * 1.0 / (count - 1) >= 1 && val > 0) { // 判断生成的金额大于0,且剩余的钱数够剩下人平分到0.01元

break;

}

}

totalVal = totalVal - val;

}

count--;

return val / 100.0;

}

}

kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

producer:生产者。consumer:消费者。topic: 消息以topic为类别记录,Kafka将消息种子(Feed)分门别类,每一类的消息称之为一个主题(Topic)。broker:以集群的方式运行,可以由一个或多个服务组成,每个服务叫做一个broker;消费者可以订阅一个或多个主题(topic),并从Broker拉数据,从而消费这些已发布的消息。每个消息(也叫作record记录,也被称为消息)是由一个key,一个value和时间戳构成。

kafka有四个核心API:应用程序使用producer API发布消息到1个或多个topic中;应用程序使用consumer API来订阅一个或多个topic,并处理产生的消息;应用程序使用streams API充当一个流处理器,从1个或多个topic消费输入流,并产生一个输出流到1个或多个topic,有效地将输入流转换到输出流;connector API允许构建或运行可重复使用的生产者或消费者,将topic链接到现有的应用程序或数据系统。

https://blog.csdn.net/zhoudaxia/article/details/38067003

计算机网络--从输入网址到获得页面的过程

(1). 浏览器查询 DNS,获取域名对应的IP地址:具体过程包括浏览器搜索自身的DNS缓存、搜索操作系统的DNS缓存、读取本地的Host文件和向本地DNS服务器进行查询等。对于向本地DNS服务器进行查询,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析(此解析具有权威性);如果要查询的域名不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析(此解析不具有权威性)。如果本地域名服务器并未缓存该网址映射关系,那么将根据其设置发起递归查询或者迭代查询;

(2). 浏览器获得域名对应的IP地址以后,浏览器向服务器请求建立链接,发起三次握手;

(3). TCP/IP链接建立起来后,浏览器向服务器发送HTTP请求;

(4). 服务器接收到这个请求,并根据路径参数映射到特定的请求处理器进行处理,并将处理结果及相应的视图返回给浏览器;

(5). 浏览器解析并渲染视图,若遇到对js文件、css文件及图片等静态资源的引用,则重复上述步骤并向服务器请求这些资源;

(6). 浏览器根据其请求到的资源、数据渲染页面,最终向用户呈现一个完整的页面。

猜你喜欢

转载自blog.csdn.net/SEUSUNJM/article/details/86588922