OpenResty高并发最佳实践--mysql操作

以你之姓@ 2022-03-28 05:59 866阅读 0赞

文章目录

        • 前言
        • 准备
        • 代码走着
        • 测试

前言

OpenResty虽然为了提高性能更多的是使用的内存数据库(OpenResty操作redis可参考:OpenResty高并发最佳实践–Redis操作),但是特殊的时候也会存在需要操作数据库的时候,下面介绍如何通过OpenResty操作mysql

准备

不了解OpenResty的可以参考以下文章
OpenResty(Nginx+Lua)高并发最佳实践
Window下基于ZeroBrane Studio开发调试OpenResty

mysql数据库安装可参考以下文章
MySQL安装及可视化工具使用

代码走着

  • mysql连接池(工具类)
    在OpenResty的lualib目录下创建testcode文件夹,用于放置我们的测试lua脚本,并在文件夹下创建mysql_factory.lua,如下图:
    20190109183327764.
    将以下代码拷贝至该文件(不需要做任何修改):

    1. local mysql = require("resty.mysql")
    2. local mysql_pool = {}
    3. --[[
    4. 先从连接池取连接,如果没有再建立连接.
    5. 返回:
    6. false,出错信息.
    7. true,数据库连接
    8. --]]
    9. function mysql_pool:get_connect(cfg)
    10. if ngx.ctx[mysql_pool] then
    11. return true, ngx.ctx[mysql_pool]
    12. end
    13. local client, errmsg = mysql:new()
    14. if not client then
    15. return false, "mysql.socket_failed: " .. (errmsg or "nil")
    16. end
    17. client:set_timeout(10000) --30
    18. local options = {
    19. host = cfg.db.prod.HOST,
    20. port = cfg.db.prod.PORT,
    21. user = cfg.db.prod.USER,
    22. password = cfg.db.prod.PASSWORD,
    23. database = cfg.db.prod.DATABASE
    24. }
    25. local result, errmsg, errno, sqlstate = client:connect(options)
    26. if not result then
    27. return false, "mysql.cant_connect: " .. (errmsg or "nil") .. ", errno:" .. (errno or "nil") ..
    28. ", sql_state:" .. (sqlstate or "nil")
    29. end
    30. local query = "SET NAMES " .. "utf8"
    31. local result, errmsg, errno, sqlstate = client:query(query)
    32. if not result then
    33. return false, "mysql.query_failed: " .. (errmsg or "nil") .. ", errno:" .. (errno or "nil") ..
    34. ", sql_state:" .. (sqlstate or "nil")
    35. end
    36. ngx.ctx[mysql_pool] = client
    37. -- 测试,验证连接池重复使用情况
    38. --[[ comments by leon1509
    39. local count, err = client:get_reused_times()
    40. ngx.say("xxx reused times" .. count);
    41. --]]
    42. return true, ngx.ctx[mysql_pool]
    43. end
    44. --[[
    45. 把连接返回到连接池
    46. set_keepalive代替close() 将开启连接池特性,可以为每个nginx工作进程,指定连接最大空闲时间,和连接池最大连接数
    47. --]]
    48. function mysql_pool:close()
    49. if ngx.ctx[mysql_pool] then
    50. -- 连接池机制,不调用 close 而是 keeplive 下次会直接继续使用
    51. -- lua_code_cache on 时才有效
    52. -- 60000 pool_max_idle_time 100connections
    53. ngx.ctx[mysql_pool]:set_keepalive(60000, 80)
    54. -- 调用了 set_keepalive,不能直接再次调用 query,会报错
    55. ngx.ctx[mysql_pool] = nil
    56. end
    57. end
    58. --[[
    59. 查询
    60. 有结果数据集时返回结果数据集
    61. 无数据数据集时返回查询影响
    62. 返回:
    63. false,出错信息,sqlstate结构.
    64. true,结果集,sqlstate结构.
    65. --]]
    66. function mysql_pool:query(sql, flag)
    67. local ret, client = self:get_connect(flag)
    68. if not ret then
    69. return false, client, nil
    70. end
    71. local result, errmsg, errno, sqlstate = client:query(sql)
    72. while errmsg == "again" do
    73. result, errmsg, errno, sqlstate = client:read_result()
    74. end
    75. self:close()
    76. if not result then
    77. errmsg = "mysql.query_failed:" .. (errno or "nil") .. (errmsg or "nil")
    78. return false, errmsg, sqlstate
    79. end
    80. return true, result, sqlstate
    81. end
    82. return mysql_pool
  • 配置文件
    同级目录下创建config_constant.lua,用于放置redis、mysql或者其他的公共配置文件
    将以下代码拷贝至该文件,具体配置数据请根据自己的mysql数据库的情况修改
    201901101001126.

    1. config = {}
    2. config.redisConfig = {
    3. redis_a = { -- your connection name
    4. --ip
    5. host = '127.0.0.1',
    6. --端口
    7. port = 6379,
    8. --密码
    9. pass = '123456789',
    10. --超时时间,如果是测试环境debug的话,这个值可以给长一点;如果是正式环境,可以设置为200
    11. timeout = 120000,
    12. --redis的库
    13. database = 0,
    14. },
    15. -- redis_b = {
    16. -- -- host = '127.0.0.1',
    17. -- -- port = 6379,
    18. -- -- pass = '',
    19. -- -- timeout = 200,
    20. -- -- database = 0,
    21. -- -- },
    22. }
    23. config.db = {
    24. prod = {
    25. HOST = "127.0.0.1",
    26. PORT = 3306,
    27. USER = "test",
    28. PASSWORD = "123456789",
    29. DATABASE = "test",
    30. }
    31. }
    32. return config

测试

  • 创建本地测试用户表,准备测试数据
    20190110095318543.
  • 编写测试Lua脚本
    前端传递用户的ID,Lua查询出对应的用户信息返回
    在testcode文件下创建mysqltest.lua并拷贝一下至该文件
    20190110101311924.

    1. --平台公共的配置文件常量
    2. local config = require "testcode.config_constant"
    3. --mysql连接池
    4. local mysqlUtil = require "mycode.mysql_factory"
    5. --用于接收前端数据的对象
    6. local args=nil
    7. --获取前端的请求方式 并获取传递的参数
    8. local request_method = ngx.var.request_method
    9. --判断是get请求还是post请求并分别拿出相应的数据
    10. if"GET" == request_method then
    11. args = ngx.req.get_uri_args()
    12. elseif "POST" == request_method then
    13. ngx.req.read_body()
    14. args = ngx.req.get_post_args()
    15. --兼容请求使用post请求,但是传参以get方式传造成的无法获取到数据的bug
    16. if (args == nil or args.data == null) then
    17. args = ngx.req.get_uri_args()
    18. end
    19. end
    20. --前端传递的id
    21. local id = args.id
    22. --组装sql语句
    23. local sql = "select * from test_table where id = "..id
    24. --执行sql语句
    25. local ret, res, sqlstate = mysqlUtil:query(sql, config.db);
    26. --判断查询结果
    27. if(ret and res ~=nil and #res>0) then
    28. --取出最新的值
    29. local user = res[1]
    30. --组装响应参数
    31. local reVa = "id:"..user.id..";</br>name:"..user.name..";</br>age:"..user.age
    32. --响应前端
    33. ngx.say(reVa)
    34. else
    35. ngx.say("未找到用户")
    36. end
  • 配置OpenResty下Nginx的Lua文件关联
    在nginx.con中的80配置下添加如下配置

    1. location /mysql
    2. {
    3. default_type text/html;
    4. #这里的lua文件的路径为绝对路径,请根据自己安装的实际路径填写
    5. #记得斜杠是/这个,从window中拷贝出来的是\这样,这样是有问题的,务必注意
    6. content_by_lua_file F:/DATA/software/other/openresty-1.13.6.2-win32/lualib/testcode/mysqltest.lua;
    7. }

    2019011010152468.

  • 重启OpenResty的Nginx
    nginx -s reload
    20190109171640307.
  • 测试
    浏览器请求:http://127.0.0.1/mysql?id=1 出现以下结果,则正常测试成功
    20190110101719850.
    20190110101752603.
    20190110101817789.
    20190110101833633.

到此,Lua操作mysql完成!!!

发表评论

表情:
评论列表 (有 0 条评论,866人围观)

还没有评论,来说两句吧...

相关阅读