首页
统计
关于
正则表达式手册
Search
1
React中编写css的几种方式
48 阅读
2
rollup.js的个人理解
41 阅读
3
【整理】Nginx基础知识
37 阅读
4
前端工程化的思考
36 阅读
5
package.json的配置参考
35 阅读
默认分类
服务器端
前端工程化
react
vue
nodejs
js+
html&css
问题集录
临时
dylin
gu
登录
/
注册
Search
标签搜索
问题
前端工程化
基础知识
css
数据库
docker
nginx
rollup.js
react
golang
js
性能优化
js基础
dylin
累计撰写
21
篇文章
累计收到
1
条评论
首页
栏目
默认分类
服务器端
前端工程化
react
vue
nodejs
js+
html&css
问题集录
临时
dylin
gu
页面
统计
关于
正则表达式手册
搜索到
4
篇与
的结果
2024-01-17
1 行命令引发的Go应用崩溃
青风 阿里云开发者;) 2025年01月15日 08:31浙江这篇文章分析了Go编译时插桩工具导致go build -race竞态检测产生崩溃的原因。不久前, 阿里云 ARMS 团队、编译器团队、MSE 团队携手合作,共同发布并开源了 Go 语言的编译时自动插桩技术。 该技术以其零侵入的特性,为 Go 应用提供了与 Java 监控能力相媲美的解决方案。开发者只需将 go build 替换为新编译命令 otel go build,就能实现对 Go 应用的全面监控和治理。问题描述近期,我们收到用户反馈,使用otel go build -race替代正常的go build -race命令后,编译生成的程序会导致崩溃。-race[3]是Go编译器的一个参数,用于检测数据竞争(data race)问题。通过为每个变量的访问添加额外检查,确保多个 goroutine 不会以不安全方式同时访问这些变量。理论上,我们的工具不应影响-race竞态检查的代码,因此出现崩溃的现象是非预期的,所以我们花了一些时间排查这个崩溃问题,崩溃的堆栈信息如下:(gdb) bt #0 0x000000000041e1c0 in __tsan_func_enter () #1 0x00000000004ad05a in racecall () #2 0x0000000000000001 in ?? () #3 0x00000000004acf99 in racefuncenter () #4 0x00000000004ae7f1 in runtime.racefuncenter (callpc=4317632) #5 0x0000000000a247d8 in ../sdk/trace.(*traceContext).TakeSnapShot (tc=<optimized out>, ~r0=...) #6 0x00000000004a2c25 in runtime.contextPropagate #7 0x0000000000480185 in runtime.newproc1.func1 () #8 0x00000000004800e2 in runtime.newproc1 (fn=0xc00030a1f0, callergp=0xc0000061e0, callerpc=12379404, retVal0=0xc0002c8f00) #9 0x000000000047fc3f in runtime.newproc.func1 () #10 0x00000000004a992a in runtime.systemstack () ....可以看到崩溃源于 __tsan_func_enter,而引发该问题的关键点是 runtime.contextPropagate。我们的工具在 runtime.newproc1 函数的开头插入了以下代码: func newproc1(fn * funcval, callergp * g, callerpc uintptr)(retVal0 * g) { // 我们插入的代码 retVal0.otel_trace_context = contextPropagate(callergp.otel_trace_context) ... } // 我们插入的代码 func contextPropagate(tls interface{}) interface{} { if tls == nil { return nil } if taker, ok := tls.(ContextSnapshoter); ok { return taker.TakeSnapShot() } return tls } // 我们插入的代码 func(tc * traceContext) TakeSnapShot() interface{ } { ... }TakeSnapShot 被 Go 编译器在函数入口和出口分别注入了 racefuncenter() 和 racefuncexit(),最终调用 __tsan_func_enter导致崩溃。由此确定崩溃问题确实是我们的注入代码导致的,继续深入排查。排查过程使用 objdump 查看 __tsan_func_enter 的源码,看到它接收两个函数参数,出错的地方是第一行 mov 0x10(%rdi),%rdx,它约等于 rdx = *(rdi + 0x10)。打印寄存器后发现 rdi = 0,根据调用约定,rdi 存放的是第一个函数参数,因此这里的问题就是函数第一个参数 thr 为 0。// void __tsan_func_enter(ThreadState *thr, void *pc); 000000000041e1c0 <__tsan_func_enter>: 41e1c0: 48 8b 57 10 mov 0x10(%rdi),%rdx 41e1c4: 48 8d 42 08 lea 0x8(%rdx),%rax 41e1c8: a9 f0 0f 00 00 test $0xff0,%eax ...那么第一个参数 thr 是谁传进来的呢?接着往上分析调用链。调用链分析出错的整个调用链是 racefuncenter(Go) -> racecall(Go) -> __tsan_func_enter(C)。需要注意的是,前两个函数都是 Go 代码,Go 函数调用 Go 函数遵循 Go 的调用约定。在 amd64 平台,前九个函数参数使用以下寄存器:另外以下寄存器用于特殊用途:后两个函数一个Go代码一个C代码,Go 调用 C 的情况下,遵循 System V AMD64 调用约定,在 Linux 平台上使用以下寄存器作为前六个参数:理解了Go和C的调用约定之后,再来看整个调用链的代码:TEXT racefuncenter<>(SB), NOSPLIT|NOFRAME, $0-0 MOVQ DX, BXx MOVQ g_racectx(R14), RARG0 // RSI存放thr MOVQ R11, RARG1 // RDI存放pc MOVQ $__tsan_func_enter(SB), AX // AX存放__tsan_func_enter函数指针 CALL racecall<>(SB) MOVQ BX, DX RETTEXT racecall<>(SB), NOSPLIT|NOFRAME, $0-0 ... CALL AX // 调用__tsan_func_enter函数指针 ...racefuncenter 将 g_racectx(R14) 和 R11 分别放入 C 调用约定的参数寄存器 RSI(RARG0) 和 RDI(RARG1),并将 __tsan_func_enter 放入 Go 调用约定的参数寄存器 RAX,然后调用 racecall,它进一步调用 __tsan_func_enter(RAX),这一系列操作大致相当于 __tsan_func_enter(g_racectx(R14), R11)。不难看出,问题的根源在于 g_racectx(R14) 为 0。根据 Go 的调用约定R14 存放当前 goroutine ,它不可能为 0 ,因此出问题的必然是R14.racectx 字段为 0。为了避免无效努力,通过调试器dlv二次确认:(dlv) p *(*runtime.g)(R14) runtime.g { racectx: 0, ... }那么为什么当前R14.racectx为0?下一步看看R14具体的状态。协程调度func newproc(fn * funcval) { gp:= getg() pc:= sys.GetCallerPC() #1 systemstack(func() { newg:= newproc1(fn, gp, pc, false, waitReasonZero) #2 ... }) }经过排查,在代码 #1 处,R14.racectx 是正常的,但到了代码 #2 处,R14.racectx 就为空了,原因是 systemstack 被调用,它有一个切换协程的动作,具体如下:// func systemstack(fn func()) TEXT runtime·systemstack(SB), NOSPLIT, $0 - 8 ... // 切换到g0协程 MOVQ DX, g(CX) MOVQ DX, R14 // 设置 R14 寄存器 MOVQ(g_sched + gobuf_sp)(DX), SP // 在g0协程上运行目标函数fn MOVQ DI, DX MOVQ 0(DI), DI CALL DI // 切换回原始协程 // ...原来systemstack有一个切换协程的动作,会先把当前协程切换成g0,然后执行fn,最后恢复原始协程执行。在 Go 语言的 GMP(Goroutine-Machine-Processor)调度模型中,每个系统级线程 M 都拥有一个特殊的g0 协程,以及若干用于执行用户任务的普通协程 g。g0 协程主要负责当前 M 上用户 g 的调度工作。由于协程调度是不可抢占的,调度过程中会临时切换到系统栈(system stack)上执行代码。在系统栈上运行的代码是隐式不可抢占的,并且垃圾回收器不会扫描系统栈。到这里我们已经知道执行 newproc1 时的协程总是 g0,而 g0.racectx是在 main 执行开始时被主动设置为 0,最终导致程序崩溃:// src/runtime/proc.go#main // The main goroutine. func main() { mp := getg().m // g0 的 racectx 仅用于作为主 goroutine 的父级。 // 不应将其用作其他目的。 mp.g0.racectx = 0 ...解决方案到这里基本上可以做一个总结了,程序崩溃的原因如下:newproc1 中插入的 contextPropagate 调用TakeSnapshot,而TakeSnapshot被 go build -race 强行在函数开始插入了 racefuncenter() 函数调用,该函数将使用 racectx。newproc1 是在 g0 协程执行下运行,该协程的 racectx 字段是 0,最终导致崩溃。一个解决办法是给TakeSnapshot加上 Go编译器的特殊指令 //go:norace,该指令需紧跟在函数声明后面,用于指定该函数的内存访问将被竞态检测器忽略,Go编译器将不会强行插入racefuncenter()调用。疑惑1runtime.newproc1 中不只调用了我们注入的contextPropagate,还有其他函数调用,为什么这些函数没有被编译器插入 race 检查的代码(如 racefuncenter)?经过排查后发现,Go 编译器会特殊处理 runtime 包,针对 runtime 包中的代码设置 NoInstrument 标志,从而跳过生成 race 检查的代码:// /src/cmd/internal/objabi/pkgspecial.go var pkgSpecialsOnce = sync.OnceValue(func() map[string]PkgSpecial { ... for _, pkg := range runtimePkgs { set(pkg, func(ps *PkgSpecial) { ps.Runtime = true ps.NoInstrument = true }) } ... })疑惑2理论上插入 //go:norace 之后问题应该得到解决,但实际上程序还是发生了崩溃。经过排查发现,TakeSnapShot 中有 map 初始化和 map 循环操作,这些操作会被编译器展开成 mapinititer() 等函数调用。这些函数直接手动启用了竞态检测器,而且无法加上 //go:norace:func mapiterinit(t *abi.SwissMapType, m *maps.Map, it *maps.Iter) { if raceenabled && m != nil { // 主动的race检查 callerpc := sys.GetCallerPC() racereadpc(unsafe.Pointer(m), callerpc, abi.FuncPCABIInternal(mapiterinit)) } ... }对此问题的解决办法是在newproc1注入的代码里面,避免使用map数据结构。总结以上就是 Go 自动插桩工具在使用 go build -race 时出现崩溃的分析全过程。通过对崩溃内容和调用链的排查,我们找到了产生问题的根本原因以及相应的解决方案。这将有助于我们在理解运行时机制的基础上,更加谨慎地编写注入到运行时的代码。最后诚邀大家试用我们的 Go自动插桩商业化产品 [2],并加入我们的钉钉群(开源群:102565007776,商业化群:35568145),共同提升Go应用监控与服务治理能力。通过群策群力,我们相信能为Go开发者社区带来更加优质的云原生体验。[1] Go自动插桩开源项目:https://github.com/alibaba/opentelemetry-go-auto-instrumentation[2] 阿里云ARMS Go Agent商业版:https://help.aliyun.com/zh/arms/tracing-analysis/monitor-go-applications/[3] Go竞态检查 https://go.dev/doc/articles/race_detector无代理ECS数据备份与高效环境搭建基于快照提供数据保护和环境搭建,实现无代理且有效可靠的数据备份,同时可以快速克隆部署开发测试环境。点击阅读原文查看详情。[https://www.aliyun.com/solution/tech-solution/ecs-backup]()
2024年01月17日
19 阅读
0 评论
0 点赞
2023-12-12
【整理】Nginx基础知识
Nginx相关知识Nginx是在前端服务部署时是很重要的一部分,也是部署的基础,学会了通过Nginx部署前端资源,才能继续后续的一系列进阶。一、了解一点简单的Nginx知识本节内容作为基础知识,如果熟悉Nginx可以略过,如果不熟悉可以实际操作一下。现在服务器安装Nginx很简单,一般只需要两行命令即可,安装完成后,启动服务。 # 安装nginx yum install -y nginx # 启动nginx systemctl start nginx # 查看nginx运行状态 systemctl status nginx当我们看到下图,说明你的Nginx运行正常,此时Nginx会启动服务,默认80端口。此时如果我们的服务器外网防火墙 80端口开启,那么访问外网IP,就能看到Nginx启动的服务Nginx的配置文件,一般位于 /etc/nginx目录下,具体内容如下:我们基本只需要关注文件 nginx.conf和 conf.d目录,下面是一份 nginx.conf配置文件,不懂也不要怕,基本都不需要改动,默认80服务已经开启了。 user nginx; # nginx进行运行的用户 error_log /var/log/nginx/error.log; # 错误日志 http { log_format main ...; # nginx日志格式 access_log /var/log/nginx/access.log main; # 日志位置 # 引入的nginx配置文件,可以将server放在该目录下,方便管理 include /etc/nginx/conf.d/*.conf; # 一个nginx服务一个server server { listen 80; # 服务启动的端口 server_name _; # 服务域名或IP root /usr/share/nginx/html; # 服务指向的文件地址 error_page 404 /404.html; # 找不到资源重定向到404页面 location = /40x.html {}; error_page 500 502 503 504 /50x.html; # 系统错误重定向50x页面 location = /50x.html {}; } # server { # listen 443; # 支持https协议 # server_name _; # root /usr/share/nginx/html; # ... # } }我们可以看到该文件分成了多层第一层:user、error_log、http第二层:log_format、access_log、include、server在http下可以有多个 Server,启动多个服务,但如果都写在一个文件里面,文件就越来越大了,那么为了便于管理多个服务,我们要对 nginx.conf进行拆分。conf.d目录下一般是空的,我们新建文件 web.conf或者任意命名的以.conf结尾的文件即可被Nginx使用,内容为: server { listen 80; server_name _; root /usr/share/nginx/html; error_page 404 /404.html; location = /40x.html {}; error_page 500 502 503 504 /50x.html; location = /50x.html {}; }由于这里使用了80端口,之前nginx.conf文件server中listen为80的可以删除了。此时nginx.conf中的文件内容为: user nginx; # nginx进行运行的用户 error_log /var/log/nginx/error.log; # 错误日志 http { log_format main ...; # nginx日志格式 access_log /var/log/nginx/access.log main; # 日志位置 # 引入的nginx配置文件,可以将server放在该目录下,方便管理 include /etc/nginx/conf.d/*.conf; }include /etc/nginx/conf.d/*.conf; 我们看到这一行语句发现,include帮助我们引用conf.d下以.conf结尾的配置文件。完成后执行nginx指令 # 检查nginx配置文件是否正确,如果错误会提示具体的错误信息 nginx -t # 重新启动nginx服务 nginx -s reload观察日志,此时发现Nginx就重新启动了,读取的是新的配置文件。其他操作nginx的指令 nginx -s stop nginx -s start二、启动一个简单的Nginx服务一台服务器或PC,安装并启动Nginx服务/data/web两个html文件 index.html, about.html1、index.html或 about.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>nginx</title> </head> <body> 通过nginx部署的第一个服务 </body> </html>2、修改 /etc/nginx/conf.d/web.conf server { listen 80; server_name localhost; root /data/web; index index.html; }执行 nginx -t确认配置文件修改没问题,再执行 nginx -s reload重启Nginx,此时我们访问外网IP(默认80端口,下面默认都是访问80端口),可以看到这样我们的静态资源文件就部署好了,通过url访问资源:http://xxxx/index.htmlhttp://xxxx/about.html三、部署单页面应用我们快速创建一个CRA单页面应用,修改App.js文件,这里使用 react-router-dom@61、Hash模式 import { HashRouter, Routes, Route, Link } from "react-router-dom"; import './App.css'; function App() { return ( <div className="App"> <HashRouter basename="/"> <div style={{marginBottom: 20}}> <Link style={{marginRight: 20}} to="/">Home</Link> <Link to="/about">About</Link> </div> <Routes> <Route path="/" element={<div>home</div>}></Route> <Route path="/about" element={<div>about</div>} /> </Routes> </HashRouter> </div> ); } export default App;我们执行 yarn build,然后将 build目录下的文件迁移到 /data/web下,再访问服务器IP,发现访问正常,路由切换也没有问题,即部署成功。2、History模式 import { BrowserRouter, ... } from "react-router-dom";将Hash模式中的代码修改为BrowserRouter,运行本地项目,路由切换正常,该路由是History模式同样执行 yarn build生成 build目录,将该目录下的文件迁移到上一步服务器的目录/data/web下,然后访问外网IP,发现渲染效果和上图一样,但是当我们点击About页面,然后刷新浏览器发现,出现了404。先说解决办法,然后解释下原因,修改Nginx配置 web.conf增加一行try_files配置,当请求的地址找不到时,重新指向index.html文件 server { listen 80; server_name localhost; root /data/www/; location / { try_files $uri $uri/ /index.html; index index.html; } }重启nginx nginx -t、nginx -s reload 再次刷新页面,发现页面访问正常了,切换也没有问题。3、为什么hash模式不会出现404,而history模式会出现404?了解下这两种模式的区别就知道答案了1)Hash模式在hash路由模式下,URL中的Hash值(#后面的部分)用来表示应用的状态或路由信息。当用户切换路由时,只有Hash部分发生变化,并没有向服务器发出请求,就做到了浏览器对于页面路由的管理。Hash模式下,URL和路由路径由#号分隔:http://example.com/#/about?query=abc当 #后面的路径发生变化时,会触发浏览器的hashchange事件,通过hashchange事件监听到路由路径的变化,从而导航到不同的路由页面。Hash模式 #后面的路径并不会作为URL出现在网络请求中。例如对于输入的example.com/#/about^[1]^ ,实际上请求的URL是example.com/^[2]^ ,所以不管输入的Hash路由路径是什么,实际网络请求的都是主域名或 IP:Port2)History模式History路由模式下,调用浏览器HTML5中 historyAPI来管理导航。URL和路径是连接在一起的,路由的路径包含在请求的URL里面,路由路径作为URL的一部分一起发送。History模式下,URL路由格式为:http://example.com/about&query=abc当我们向服务器发出请求时,服务器会请求对应的路径的资源综上,当我们打开入口文件index.html的路径时,切换url此时是本地路由,访问正常,但是当我们处于非入口页面时,刷新浏览器,此时发出请求,由于服务器就找不到资源路径了,变成了404。而对于Hash模式来说,总是请求的根路径,所以不会出现这种情况。四、配置反向代理、负载均衡1、反向代理反向代理的用途很多,这里我们看一个常用的,代理请求的接口。我们在发布时前端的域名和后端api服务的域名经常不一致,此时就可以使用Nginx配置反向代理来解决这个问题。 server { location /api { proxy_pass http://backend1.example.com; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }代理的时候要注意添加必要的参数,帮助后端获取一些客户端的请求数据proxy_set_header Host $host; :客户端请求的主机名(Host),不加的话,后端无法获取主机名信息proxy_set_header X-Real-IP $remote_addr;:用户的真实IP(X-Real-IP),如果不设置,后端只能拿到代理服务器的IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;代理链路,如果用户中间经过了多个代理服务器,如果不加这个参数,那么后端服务将无法获取用户的真实来源2、负载均衡Nginx可以作为负载均衡服务器使用,通过配置upstream来分发流量,同时可以配置一些参数:weight:分发权重ip_hash:配置始终将ip的请求始终转发到同一台后端服务器。max_fails: 将某个后台服务标记为不可用之前,允许请求失败的次数backup:标记当前服务为备用服务down:暂时不可用 upstream api { ip_hash; server backend1.example.com; server backend2.example.com; # server backend1.example.com weight=5; } server { location /api { proxy_pass http://api; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }五、配置nginx日志Nginx日志也是很重要的一个内容,在我们请求资源出现问题时,要排查请求的资源是否到达Nginx,而且请求日志可以记录很多有用的信息。 log_format gzip '$remote_addr - $remote_user [$time_local] ' : '"$request" $status $bytes_sent ' : '"$http_referer" "$http_user_agent" "$gzip_ratio"'; access_log /var/logs/nginx-access.log gzip buffer=32k;nginx日志主要涉及 access_log,log_formatlog_format: 日志格式,通过nginx内置的变量来读取和排列,通常默认即可access_log: 日志输出的地址、是否压缩、buffer是否当日志大于32k后吸入磁盘六、其他常用配置1、配置Gzip压缩作为前端性能优化的一种方式,Gzip是简单且有效的,尽管目前前端对于静态资源会进行压缩,但Gzip依然可以在网络传输过程中对文件进行压缩下面这些字段可以放在 http、server、location指令模块 http { # 开启关闭 gzip on; # 压缩的文件类型 gzip_types text/plain text/css application/javascript; # 过小的文件没必要压缩 gzip_min_length 1000; # 单位Byte gzip_comp_level 5; # 压缩比,默认1,范围时1-9,值越大压缩比最大,但处理最慢,所以设置5左右比较合理。 }2、配置请求头允许客户端请求在http请求中添加以下划线格式命名的参数该字段可以放在 http指令模块 http { underscores_in_headers on; } ``` **允许客户端上传文件最大不超过1M,在开发上传接口时一定要注意,否则导致上传失败** 该字段可以放在`http、server、location`指令模块 http { client_max_body_size 1m; } ### 3、浏览器缓存配置 **缓存也是前端优化的一个重点,合理的缓存可以提高用户访问速度** 该字段可以放在`http、server、location`指令模块 配置浏览器缓存的有三个地方 #### 1)后端服务,配置请求头 后端根据语言不同,配置关键字段即可 #### 2)代理服务器(Nginx)配置缓存请求头 location /static { # /static匹配到的资源有效期设置为1d; expires 1d; # /设置资源有效期为一周; # expires max-age=604800; # 设置浏览器可以被缓存,设置7天后资源过期 add_header Cache-Control "public, max-age=604800"; # 阻止浏览器缓存动态内容 # add_header Cache-Control "no-cache, no-store, must-revalidate"; # 禁用浏览器缓存 # add_header Cache-Control "no-store, private, max-age=0";} 我们发现响应头的过期时间更新了  #### 3)在前端资源中通过meta声明缓存信息 <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"><meta http-equiv="Expires" content="0"> ### 4、跨域处理 > 通过反向代理,已经处理了请求域名和端口不一致的跨域问题,但有局限性。Nginx有专门方法配置请求资源的跨域 该字段可以放在 `server、location`指令模块,通过配置头部字段,做跨域处理 server {location / { # 允许所有来源的跨域请求 add_header Access-Control-Allow-Origin *; # 允许特定的HTTP方法(GET、POST等) add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE"; # 允许特定的HTTP请求头字段 add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"; # 响应预检请求的最大时间 add_header Access-Control-Max-Age 3600; # 允许携带身份凭证(如Cookie) add_header Access-Control-Allow-Credentials true; # 处理 OPTIONS 预检请求 if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE"; add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"; add_header Access-Control-Max-Age 3600; add_header Access-Control-Allow-Credentials true; add_header Content-Length 0; add_header Content-Type text/plain; return 204; } }}
2023年12月12日
37 阅读
0 评论
0 点赞
2023-12-12
云服务器Docker内部署服务后,端口无法访问?
云服务器Docker内部署服务后,端口无法访问,可以按照以下思路进行排查: 以【docker run --name my-nginx -d -p 9395:80 nginx】举例:查看Docker映射是否正确,可使用docker ps命令查看。Docker是否设置端口映射,你的nginx是否放开80端口外部访问判断云服务器安全组是否放通相应端口。例如:查看你的云服务器防火墙是否放开9395端口外部访问。在/etc/sysctl.conf文件内,找到net.ipv4.ip_forward,将默认的参数0改为1,然后执行sysctl -p命令即可。总结:当你检测你的操作都没问题,还不行的话, 只能是服务器的问题,既然是服务器的问题,那就得找客服。
2023年12月12日
28 阅读
0 评论
0 点赞
2023-12-11
本地navcat怎么连接云服务器里的数据库
本地navcat怎么连接云服务器里的数据库首先要检查云服务器里的应用管理-是否有对应的数据库。然后通过运行 cat ~lighthouse/credentials.txt 来查看数据库的登录密码(云服务器数据库的默认密码强度足够高,如果你想自己设置,一定要设置足够复杂的密码,这是血淋淋的教训)。然后把你的ip 端口 用户名 密码输入navcat。下面是可能遇到的问题:1130 - Host '222.92.143.173'is not allowed to connect to this MariaDB server错误消息“1130 - Host '222.92.143.173' is not allowed to connect to this MariaDB server”表明来自特定IP地址(在本例中是222.92.143.173)的客户端尝试连接到MariaDB服务器时,该服务器的配置不允许来自该IP的连接。这通常是因为MariaDB的 user表中的 host字段没有为相应的用户配置为允许该IP地址或任何IP地址(通常使用通配符 %表示)。要解决这个问题,您可以采取以下步骤:连接数据库ssh远程到对于的linux服务器,使用mysql -u root -p 回车输入密码再次回车进行登录登录MariaDB后,显示MariaDB [(none)]> 如果你希望选择一个数据库作为当前工作数据库,可以使用 USE 语句。例如,如果你想选择名为 mydatabase 的数据库,可以执行以下命令:USE mydatabase;访问MariaDB服务器:您需要有足够的权限来登录到MariaDB服务器。这通常意味着您需要服务器的SSH访问权限以及MariaDB的root用户或其他具有足够权限的用户的凭据。检查用户权限:登录到MariaDB后,您可以检查 mysql.user表来查看特定用户的权限设置。使用以下SQL命令:SELECT user, host FROM mysql.user WHERE user = 'your_username';将 your_username替换为尝试连接的用户名。这将显示该用户的所有主机条目。更新用户权限:如果 host字段中没有条目允许来自222.92.143.173的连接,您可能需要更新它。如果您想允许该用户从任何IP地址连接,可以使用以下命令(注意,这可能会带来安全风险,因为它允许从任何网络地址进行连接):GRANT ALL PRIVILEGES ON *.* TO 'your_username'@'%' IDENTIFIED BY 'your_password' WITH GRANT OPTION; FLUSH PRIVILEGES;或者,如果您只想允许来自特定IP的连接,可以这样做:GRANT ALL PRIVILEGES ON *.* TO 'your_username'@'222.92.143.173' IDENTIFIED BY 'your_password' WITH GRANT OPTION; FLUSH PRIVILEGES;但是,请注意,如果用户已经存在并且您只是想要更改其主机设置,您可能需要先删除现有的用户条目(这可能会导致数据丢失,除非您非常确定自己在做什么),然后重新创建它,或者使用 UPDATE语句直接修改 mysql.user表(这通常不推荐,因为它可能会绕过MariaDB的安全机制)。考虑安全性:允许从任何IP地址连接可能会使您的数据库面临安全风险。相反,考虑配置防火墙规则以限制对MariaDB端口的访问,并仅允许受信任的IP地址进行连接。重启MariaDB服务:在某些情况下,您可能需要重启MariaDB服务才能使更改生效。这可以通过您的服务器的服务管理工具来完成。测试连接:最后,从222.92.143.173或其他允许的IP地址尝试重新连接,以确保更改已正确应用。注意云服务器的防火墙防火墙只控制服务器的入流量,出流量默认允许所有请求,可以设置允许或禁止公网或内网对轻量应用服务器实例的访问,未配置规则等同于禁止访问。如何配置防火墙规则如有发现无法访问接口和静态资源的情况,注意检查防火墙。
2023年12月11日
34 阅读
0 评论
1 点赞