当前位置: 首页 > news >正文

创意网站展示建设网站有哪些目的是什么意思

创意网站展示,建设网站有哪些目的是什么意思,水果网站建设策划书,wordpress怎么优化精简目录 多级缓存 1.什么是多级缓存 2.JVM进程缓存 2.1 导入案例 2.2 初识Caffeine 2.3 实现JVM进程缓存 2.3.1 需求 2.3.2 实现 3.Lua语法入门 3.1 初识Lua 3.1 HelloWorld 3.2.变量和循环 3.2.1 Lua的数据类型 3.2.3 循环 3.3 条件控制、函数 3.3.1 函数 3.3.2 条件控制 3.3.3 案… 目录 多级缓存 1.什么是多级缓存 2.JVM进程缓存 2.1 导入案例 2.2 初识Caffeine 2.3 实现JVM进程缓存 2.3.1 需求 2.3.2 实现 3.Lua语法入门 3.1 初识Lua 3.1 HelloWorld 3.2.变量和循环 3.2.1 Lua的数据类型 3.2.3 循环 3.3 条件控制、函数 3.3.1 函数 3.3.2 条件控制 3.3.3 案例 4.实现多级缓存 4.1 安装OpenResty 4.2 OpenResty快速入门 4.2.1 反向代理流程 4.2.2 OpenResty监听请求 4.2.3 编写item.lua 4.3 请求参数处理 4.3.1 获取参数的API 4.3.2 获取参数并返回 4.4 查询Tomcat 4.4.1 发送http请求的API 4.4.2 封装http工具 4.4.3 CJSON工具类 4.4.4 实现Tomcat查询 多级缓存 1.什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后先查询Redis如果未命中则查询数据库如图 存在下面的问题 •请求要经过Tomcat处理Tomcat的性能成为整个系统的瓶颈 •Redis缓存失效时会对数据库产生冲击 多级缓存就是充分利用请求处理的每个环节分别添加缓存减轻Tomcat压力提升服务性能 浏览器访问静态资源时优先读取浏览器本地缓存 访问非静态资源ajax查询数据时访问服务端 请求到达Nginx后优先读取Nginx本地缓存 如果Nginx本地缓存未命中则去直接查询Redis不经过Tomcat 如果Redis查询未命中则查询Tomcat 请求进入Tomcat后优先查询JVM进程缓存 如果JVM进程缓存未命中则查询数据库 在多级缓存架构中Nginx内部需要编写本地缓存查询、Redis查询、Tomcat查询的业务逻辑因此这样的nginx服务不再是一个反向代理服务器而是一个编写业务的Web服务器了。因此这样的业务Nginx服务也需要搭建集群来提高并发再有专门的nginx服务来做反向代理。另外我们的Tomcat服务将来也会部署为集群模式。 可见多级缓存的关键有两个 一个是在nginx中编写业务实现nginx本地缓存、Redis、Tomcat的查询 另一个就是在Tomcat中实现JVM进程缓存 其中Nginx编程则会用到OpenResty框架结合Lua这样的语言。 反向代理   现在页面是假数据展示的。我们需要向服务器发送ajax请求查询商品数据。 打开控制台可以看到页面有发起ajax查询数据 而这个请求地址同样是80端口所以被当前的nginx反向代理了。 查看nginx的conf目录下的nginx.conf文件 2.JVM进程缓存 2.1 导入案例 2.2 初识Caffeine 缓存在日常开发中启动至关重要的作用由于是存储在内存中数据的读取速度是非常快的能大量减少对数据库的访问减少数据库的压力。我们把缓存分为两类 分布式缓存例如Redis 优点存储容量更大、可靠性更好、可以在集群间共享 缺点访问缓存有网络开销 场景缓存数据量较大、可靠性要求较高、需要在集群间共享 进程本地缓存例如HashMap、GuavaCache 优点读取本地内存没有网络开销速度更快 缺点存储容量有限、可靠性较低、无法共享 场景性能要求较高缓存数据量较小 Caffeine是一个基于Java8开发的提供了近乎最佳命中率的高性能的本地缓存库。目前Spring内部的缓存使用的就是Caffeine。 缓存使用的基本API Test void testBasicOps() {// 构建cache对象CacheString, String cache Caffeine.newBuilder().build();// 存数据cache.put(gf, 迪丽热巴);// 取数据String gf cache.getIfPresent(gf);System.out.println(gf gf);// 取数据包含两个参数// 参数一缓存的key// 参数二Lambda表达式表达式参数就是缓存的key方法体是查询数据库的逻辑// 优先根据key查询JVM缓存如果未命中则执行参数二的Lambda表达式String defaultGF cache.get(defaultGF, key - {// 根据key去数据库查询数据return 柳岩;});System.out.println(defaultGF defaultGF); } Caffeine既然是缓存的一种肯定需要有缓存的清除策略不然的话内存总会有耗尽的时候。 Caffeine提供了三种缓存驱逐策略 基于容量设置缓存的数量上限 // 创建缓存对象 CacheString, String cache Caffeine.newBuilder().maximumSize(1) // 设置缓存大小上限为 1.build(); 基于时间设置缓存的有效时间 // 创建缓存对象 CacheString, String cache Caffeine.newBuilder()// 设置缓存有效期为 10 秒从最后一次写入开始计时 .expireAfterWrite(Duration.ofSeconds(10)) .build(); 基于引用设置缓存为软引用或弱引用利用GC来回收缓存数据。性能较差不建议使用。 注意在默认情况下当一个缓存元素过期的时候Caffeine不会自动立即将其清理和驱逐。而是在一次读或写操作后或者在空闲时间完成对失效数据的驱逐。 2.3 实现JVM进程缓存 2.3.1 需求 利用Caffeine实现下列需求 给根据id查询商品的业务添加缓存缓存未命中时查询数据库 给根据id查询商品库存的业务添加缓存缓存未命中时查询数据库 缓存初始大小为100 缓存上限为10000 2.3.2 实现 首先我们需要定义两个Caffeine的缓存对象分别保存商品、库存的缓存数据。 在item-service的com.heima.item.config包下定义CaffeineConfig类 package com.heima.item.config;import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import com.heima.item.pojo.Item; import com.heima.item.pojo.ItemStock; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public class CaffeineConfig {Beanpublic CacheLong, Item itemCache(){return Caffeine.newBuilder().initialCapacity(100).maximumSize(10_000).build();}Beanpublic CacheLong, ItemStock stockCache(){return Caffeine.newBuilder().initialCapacity(100).maximumSize(10_000).build();} } 然后修改item-service中的com.heima.item.web包下的ItemController类添加缓存逻辑 RestController RequestMapping(item) public class ItemController {Autowiredprivate IItemService itemService;Autowiredprivate IItemStockService stockService;Autowiredprivate CacheLong, Item itemCache;Autowiredprivate CacheLong, ItemStock stockCache;// ...其它略GetMapping(/{id})public Item findById(PathVariable(id) Long id) {return itemCache.get(id, key - itemService.query().ne(status, 3).eq(id, key).one());}GetMapping(/stock/{id})public ItemStock findStockById(PathVariable(id) Long id) {return stockCache.get(id, key - stockService.getById(key));} } 3.Lua语法入门 Nginx编程需要用到Lua语言因此我们必须先入门Lua的基本语法。 3.1 初识Lua Lua 是一种轻量小巧的脚本语言用标准C语言编写并以源代码形式开放 其设计目的是为了嵌入应用程序中从而为应用程序提供灵活的扩展和定制功能。 Lua经常嵌入到C语言开发的程序中例如游戏开发、游戏插件等。 Nginx本身也是C语言开发因此也允许基于Lua做拓展。 3.1 HelloWorld CentOS7默认已经安装了Lua语言环境所以可以直接运行Lua代码。 1在Linux虚拟机的任意目录下新建一个hello.lua文件 2添加下面的内容 print(Hello World!)   3运行 3.2.变量和循环 3.2.1 Lua的数据类型 另外Lua提供了type()函数来判断一个变量的数据类型 Lua中的table类型既可以作为数组又可以作为Java中的map来使用。数组就是特殊的tablekey是数组角标而已 -- 声明数组 key为角标的 table local arr {java, python, lua} -- 声明table类似java的map local map {nameJack, age21} Lua中的数组角标是从1开始 -- 访问数组lua数组的角标从1开始 print(arr[1]) Lua中的table可以用key来访问 -- 访问table print(map[name]) print(map.name) 3.2.3 循环 对于table我们可以利用for循环来遍历。不过数组和普通table遍历略有差异。 遍历数组 -- 声明数组 key为索引的 table local arr {java, python, lua} -- 遍历数组 for index,value in ipairs(arr) doprint(index, value) end 遍历普通table -- 声明map也就是table local map {nameJack, age21} -- 遍历table for key,value in pairs(map) doprint(key, value) end 3.3 条件控制、函数 3.3.1 函数 定义函数的语法 function 函数名( argument1, argument2..., argumentn)-- 函数体[return 返回值] end 3.3.2 条件控制 类似Java的条件控制例如if、else语法 if(布尔表达式) then--[ 布尔表达式为 true 时执行该语句块 --] else--[ 布尔表达式为 false 时执行该语句块 --] end与java不同布尔表达式中的逻辑运算是基于英文单词: 3.3.3 案例 需求自定义一个函数可以打印table当参数为nil时打印错误信息 function printArr(arr)if not arr thenprint(数组不能为空)endfor index, value in ipairs(arr) doprint(value)end end 4.实现多级缓存 多级缓存的实现离不开Nginx编程而Nginx编程又离不开OpenResty。 4.1 安装OpenResty OpenResty® 是一个基于 Nginx的高性能 Web 平台用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。具备下列特点 具备Nginx的完整功能 基于Lua语言进行扩展集成了大量精良的 Lua 库、第三方模块 允许使用Lua自定义业务逻辑、自定义库 安装OpenResty资料 4.2 OpenResty快速入门 其中 windows上的nginx用来做反向代理服务将前端的查询商品的ajax请求代理到OpenResty集群 OpenResty集群用来编写多级缓存业务 4.2.1 反向代理流程 现在商品详情页使用的是假的商品数据。不过在浏览器中可以看到页面有发起ajax请求查询真实商品数据。 这个请求如下 请求地址是localhost端口是80就被windows上安装的Nginx服务给接收到了。然后代理给了OpenResty集群 我们需要在OpenResty中编写业务查询商品数据并返回到浏览器。 但是这次我们先在OpenResty接收请求返回假的商品数据。 4.2.2 OpenResty监听请求 OpenResty的很多功能都依赖于其目录下的Lua库需要在nginx.conf中指定依赖库的目录并导入依赖 1添加对OpenResty的Lua模块的加载 修改/usr/local/openresty/nginx/conf/nginx.conf文件在其中的http下面添加下面代码 #lua 模块 lua_package_path /usr/local/openresty/lualib/?.lua;;; #c模块 lua_package_cpath /usr/local/openresty/lualib/?.so;;; 2监听/api/item路径 修改/usr/local/openresty/nginx/conf/nginx.conf文件在nginx.conf的server下面添加对/api/item这个路径的监听 location /api/item {# 默认的响应类型default_type application/json;# 响应结果由lua/item.lua文件来决定content_by_lua_file lua/item.lua; } 这个监听就类似于SpringMVC中的GetMapping(/api/item)做路径映射。 而content_by_lua_file lua/item.lua则相当于调用item.lua这个文件执行其中的业务把结果返回给用户。相当于java中调用service。 4.2.3 编写item.lua 1在/usr/loca/openresty/nginx目录创建文件夹lua 2在/usr/loca/openresty/nginx/lua文件夹下新建文件item.lua 3编写item.lua返回假数据 item.lua中利用ngx.say()函数返回数据到Response中 ngx.say({id:10001,name:SALSA AIR,title:RIMOWA 21寸托运箱拉杆箱 SALSA AIR系列果绿色 820.70.36.4,price:17900,image:https://m.360buyimg.com/mobilecms/s720x720_jfs/t6934/364/1195375010/84676/e9f2c55f/597ece38N0ddcbc77.jpg!q70.jpg.webp,category:拉杆箱,brand:RIMOWA,spec:,status:1,createTime:2019-04-30T16:00:00.00000:00,updateTime:2019-04-30T16:00:00.00000:00,stock:2999,sold:31290}) 4重新加载配置 nginx -s reload 4.3 请求参数处理 上面在OpenResty接收前端请求但是返回的是假数据。 要返回真实数据必须根据前端传递来的商品id查询商品信息才可以。 那么如何获取前端传递的商品参数呢 4.3.1 获取参数的API 4.3.2 获取参数并返回 在前端发起的ajax请求如图 可以看到商品id是以路径占位符方式传递的因此可以利用正则表达式匹配的方式来获取ID 1获取商品id 修改/usr/loca/openresty/nginx/nginx.conf文件中监听/api/item的代码利用正则表达式获取ID location ~ /api/item/(\d) {# 默认的响应类型default_type application/json;# 响应结果由lua/item.lua文件来决定content_by_lua_file lua/item.lua; } 2拼接ID并返回 修改/usr/loca/openresty/nginx/lua/item.lua文件获取id并拼接到结果中返回 -- 获取商品id local id ngx.var[1] -- 拼接并返回 ngx.say({id: .. id .. ,name:SALSA AIR,title:RIMOWA 21寸托运箱拉杆箱 SALSA AIR系列果绿色 820.70.36.4,price:17900,image:https://m.360buyimg.com/mobilecms/s720x720_jfs/t6934/364/1195375010/84676/e9f2c55f/597ece38N0ddcbc77.jpg!q70.jpg.webp,category:拉杆箱,brand:RIMOWA,spec:,status:1,createTime:2019-04-30T16:00:00.00000:00,updateTime:2019-04-30T16:00:00.00000:00,stock:2999,sold:31290}) 3重新加载并测试 运行命令以重新加载OpenResty配置 nginx -s reload 刷新页面可以看到结果中已经带上了ID 4.4 查询Tomcat 拿到商品ID后本应去缓存中查询商品信息不过目前我们还未建立nginx、redis缓存。因此这里我们先根据商品id去tomcat查询商品信息。我们实现如图部分 需要注意的是我们的OpenResty是在虚拟机Tomcat是在Windows电脑上。两者IP一定不要搞错了。 4.4.1 发送http请求的API nginx提供了内部API用以发送http请求 local resp ngx.location.capture(/path,{method ngx.HTTP_GET, -- 请求方式args {a1,b2}, -- get方式传参数 }) 返回的响应内容包括 resp.status响应状态码 resp.header响应头是一个table resp.body响应体就是响应数据 注意这里的path是路径并不包含IP和端口。这个请求会被nginx内部的server监听并处理。 但是我们希望这个请求发送到Tomcat服务器所以还需要编写一个server来对这个路径做反向代理 location /path {# 这里是windows电脑的ip和Java服务端口需要确保windows防火墙处于关闭状态proxy_pass http://192.168.150.1:8081; } 原理如图 4.4.2 封装http工具 下面我们封装一个发送Http请求的工具基于ngx.location.capture来实现查询tomcat。 1添加反向代理到windows的Java服务 因为item-service中的接口都是/item开头所以我们监听/item路径代理到windows上的tomcat服务。 修改 /usr/local/openresty/nginx/conf/nginx.conf文件添加一个location location /item {proxy_pass http://192.168.150.1:8081; } 以后只要我们调用ngx.location.capture(/item)就一定能发送请求到windows的tomcat服务。 2封装工具类 之前我们说过OpenResty启动时会加载以下两个目录中的工具文件 所以自定义的http工具也需要放到这个目录下。 在/usr/local/openresty/lualib目录下新建一个common.lua文件 vi /usr/local/openresty/lualib/common.lua 内容如下: -- 封装函数发送http请求并解析响应 local function read_http(path, params)local resp ngx.location.capture(path,{method ngx.HTTP_GET,args params,})if not resp then-- 记录错误信息返回404ngx.log(ngx.ERR, http请求查询失败, path: , path , , args: , args)ngx.exit(404)endreturn resp.body end -- 将方法导出 local _M { read_http read_http } return _M 这个工具将read_http函数封装到_M这个table类型的变量中并且返回这类似于导出。 使用的时候可以利用require(common)来导入该函数库这里的common是函数库的文件名。 3实现商品查询 最后我们修改/usr/local/openresty/lua/item.lua文件利用刚刚封装的函数库实现对tomcat的查询 -- 引入自定义common工具模块返回值是common中返回的 _M local common require(common) -- 从 common中获取read_http这个函数 local read_http common.read_http -- 获取路径参数 local id ngx.var[1] -- 根据id查询商品 local itemJSON read_http(/item/.. id, nil) -- 根据id查询商品库存 local itemStockJSON read_http(/item/stock/.. id, nil) 这里查询到的结果是json字符串并且包含商品、库存两个json字符串页面最终需要的是把两个json拼接为一个json 这就需要我们先把JSON变为lua的table完成数据整合后再转为JSON。 4.4.3 CJSON工具类 OpenResty提供了一个cjson的模块用来处理JSON的序列化和反序列。 1引入cjson模块 local cjson require cjson 2序列化 local obj {     name jack,     age 21 } -- 把 table 序列化为 json local json cjson.encode(obj) 3反序列化 local json {name: jack, age: 21} -- 反序列化 json为 table local obj cjson.decode(json); print(obj.name) 4.4.4 实现Tomcat查询 下面我们修改之前的item.lua中的业务添加json处理功能 -- 导入common函数库 local common require(common) local read_http common.read_http -- 导入cjson库 local cjson require(cjson)-- 获取路径参数 local id ngx.var[1] -- 根据id查询商品 local itemJSON read_http(/item/.. id, nil) -- 根据id查询商品库存 local itemStockJSON read_http(/item/stock/.. id, nil)-- JSON转化为lua的table local item cjson.decode(itemJSON) local stock cjson.decode(stockJSON)-- 组合数据 item.stock stock.stock item.sold stock.sold-- 把item序列化为json 返回结果 ngx.say(cjson.encode(item))
http://www.hkea.cn/news/14531952/

相关文章:

  • 宁波网站搭建定制非模板网站建设四川手机网
  • 网站建设外包平台wordpress 效率插件
  • 东海县城乡建设局网站果洛wap网站建设公司
  • 网站标题空格做网站模板的网页名称是m开头
  • 免费主页空间的网站创建一个网站要多少钱
  • 网站管理强化阵地建设王烨当兵
  • 公司简介模板免费图片seo技术分类
  • 如何创建网站的第一步培训机构线上引流推广方法
  • 设计网站页面出现问题安徽省铜陵市建设局网站
  • php网站开发实施方案网站用户 分析
  • 网站建设与管理题目做营销网站
  • 外贸公司英文网站建设代理网页游戏需要什么条件啊
  • 广州网站营销seo费用做网站专题怎样添加微博
  • 公司网站建设企业网站深圳做网站排名哪家专业
  • 网站流量怎么挣钱阿里巴巴做网站的
  • 网站更换名称需要重新备案吗武功做网站
  • 中国大型网站灰蓝 网站模板
  • 第一次和别人女友做网站安全邮箱注册网站
  • 网站在百度无法验证码怎么办啊如何自创游戏
  • 地方网站怎么做推广erp系统页面
  • 网站建设公司 枫子伽叩罗伯特清崎说的网络营销是什么
  • 设计网站定制公司江门特色
  • 网站建设的总结100字网站开发设计概述
  • 建设工程网站新专家入库wordpress数据库清理sql
  • 艺术创意设计烟台seo推广优化
  • 怎么自助建站价格合理的网站建设
  • 设计师招聘网站有哪些江苏环泰建设有限公司网站
  • 广州做大型网站建设网页编辑器哪个好
  • 用腾讯云做淘宝客购物网站视频东阳网站制作
  • 怎么开网站深圳网站建设公司联