节点的 Apache 反向代理 - 连接被拒绝:AH00957
Apache reverse proxy to Node - Connection refused: AH00957
我正在尝试使用默认版本的 20.04 服务器 ubuntu 使用 apache 和节点工作的全新基于云的服务器。节点服务器似乎 运行 没有问题报告 4006 端口已打开。但是我相信我的 apache 配置不是。该请求将挂起很长时间。节点终端中没有显示任何错误。所以故障一定出在我的 apache 配置上,因为我们收到以下 apache 错误并且没有 JS 错误。
一段时间后请求错误
502 proxy error
Apache 错误日志
[Sun Oct 17 20:58:56.608793 2021] [proxy:error] [pid 1596878] (111)Connection refused: AH00957: HTTP: attempt to connect to [::1]:4006 (localhost) failed
[Sun Oct 17 20:58:56.608909 2021] [proxy_http:error] [pid 1596878] [client 207.46.13.93:27392] AH01114: HTTP: failed to make connection to backend: localhost
虚拟主机
<VirtualHost IP_ADDRESS:80>
ServerName api.aDomain.com
Redirect permanent / https://api.aDomain.com/
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost IP_ADDRESS:443>
ServerName api.aDomain.com
ProxyRequests on
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
ProxyPass / http://localhost:4006/
ProxyPassReverse / http://localhost:4006/
#certificates SSL
SSLEngine on
SSLCACertificateFile /etc/ssl/api.aDomain.com/apimini.ca
SSLCertificateFile /etc/ssl/api.aDomain.com/apimini.crt
SSLCertificateKeyFile /etc/ssl/api.aDomain.com/apimini.key
ErrorLog ${APACHE_LOG_DIR}/error_api.aDomain.com.log
CustomLog ${APACHE_LOG_DIR}/access_api.aDomain.com.log combined
</VirtualHost>
</IfModule>
终端输出
[nodemon] 1.19.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `babel-node -r dotenv/config --inspect=9229 index.js`
Debugger listening on ws://127.0.0.1:9229/c1fcf271-aea8-47ff-910e-fe5a91fce6d2
For help, see: https://nodejs.org/en/docs/inspector
Browserslist: caniuse-lite is outdated. Please run next command `npm update`
Server ready at http://localhost:4006
节点服务器
import cors from 'cors'
import scrape from './src/api/routes/scrape'
const express = require('express')
const { ApolloServer, gql } = require('apollo-server-express')
const { postgraphile } = require('postgraphile')
const ConnectionFilterPlugin = require('postgraphile-plugin-connection-filter')
const dbHost = process.env.DB_HOST
const dbPort = process.env.DB_PORT
const dbName = process.env.DB_NAME
const dbUser = process.env.DB_USER
const dbPwd = process.env.DB_PWD
const dbUrl = dbPwd
? `postgres://${dbUser}:${dbPwd}@${dbHost}:${dbPort}/${dbName}`
: `postgres://${dbHost}:${dbPort}/${dbName}`
var corsOptions = {
origin: '*',
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
}
async function main() {
// Construct a schema, using GraphQL schema language
const typeDefs = gql`
type Query {
hello: String
}
`
// Provide resolver functions for your schema fields
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
}
const server = new ApolloServer({ typeDefs, resolvers })
const app = express()
app.use(cors(corsOptions))
app.use(
postgraphile(process.env.DATABASE_URL || dbUrl, 'public', {
appendPlugins: [ConnectionFilterPlugin],
watchPg: true,
graphiql: true,
enhanceGraphiql: true,
})
)
server.applyMiddleware({ app })
//Scraping Tools
scrape(app)
const port = 4006
await app.listen({ port })
console.log(` Server ready at http://localhost:${port}`)
}
main().catch(e => {
console.error(e)
process.exit(1)
})
已启用 Apache 模组
/etc/apache2/mods-enabled/proxy.conf
/etc/apache2/mods-enabled/proxy.load
/etc/apache2/mods-enabled/proxy_http.load
更新错误日志
[Thu Oct 21 10:59:22.560608 2021] [proxy_http:error] [pid 10273] (70007)The timeout specified has expired: [client 93.115.195.232:8963] AH01102: error reading status line from remote server 127.0.0.1:4006, referer: https://miniatureawards.com/
[Thu Oct 21 10:59:22.560691 2021] [proxy:error] [pid 10273] [client 93.115.195.232:8963] AH00898: Error reading from remote server returned by /graphql, referer: https://miniatureawards.com/
如果您使用 docker 作为您的节点服务器,那么它可能设置不正确
我不是这方面的专家,但我有类似的设置;我使用 socket.io
来服务 WebSockets...
从你的帖子来看,你似乎也不需要代理 WebSockets,你日志中显示的似乎只是为了调试目的(如果我错了请纠正我)。
遵循我的 Apache 配置的核心:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:4006/ [P,L]
<Location />
ProxyPass http://127.0.0.1:4006/ retry=2
ProxyPassReverse http://127.0.0.1:4006/
</Location>
另外几个建议。
Warning
Do not enable proxying with ProxyRequests
until you have secured your server. Open proxy servers are dangerous both to your network and to the Internet at large.
来源:https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxyrequests
我不知道您主机上的 IPV6 设置是什么,您可以尝试在 Apache 配置中使用 127.0.0.1
而不是 localhost
来尝试强制 Apache 使用 IPV4。
我无法准确预测到底发生了什么,它可能是 NodeJS 应用程序崩溃并且不再 运行ning 或者存在配置错误的 Apache 文件。但我坚信这种情况将通过从顶部做事来解决。
此步骤将通过更新 unbuntu 包、安装所需的应用程序、配置 Apache 文件以及使用 NodeJS 和 Apache 设置反向代理。
只是不要触摸您的 NodeJS 文件和其他与代码相关的应用程序,它们是安全的。您也可以备份以确保。该 ubuntu 服务器示例数据库应用程序上的其他 运行ning 应用程序如 MySQL
一样会很好并且仍然是 运行ning.
1.首先我们需要更新 ubuntu 包并安装 Apache 和 NodeJS
$ sudo apt update
$ sudo apt install apache2 npm
2。 运行 这个命令使我们能够使用 Apache 作为反向代理服务器
sudo a2enmod proxy proxy_http rewrite headers expires
3。创建 Apache 虚拟主机文件。
此命令将允许您使用 ubuntu 终端作为文本编辑器,按照终端的指南和提示进行编写。
注意:
将“yourSite.com”更改为您网站的域。文件名应该不是真正重要的。但我认为最好以您的站点域名命名,这样您就可以识别它。
$ sudo nano /etc/apache2/sites-available/yourSite.com.conf
4.使用 nano 编辑器是为您的站点编写 Apache 配置文件。
注意:这部分很关键,请注意
将您的 ServerName 和 ServerAlias 更改为您的站点域名。
ProxyPass 和 ProxyPassReverse 这个有两个参数。
第一个是反斜杠“/” 这是您的 NodeJS 应该位于的绝对路径,因为它的单个反斜杠表示它是您的主目录。
第二个是您的 NodeJS 应用程序的 url“http://127.0.0.1:3000/”。注意它的端口“3000”,您可能需要将其替换为您在 NodeJS 应用程序中使用的端口。
<VirtualHost *:80>
ServerName example.com // replace this with site domain name without www at the beginning
ServerAlias www.example.com // replace this with site domain name beginning with www. + yourdomainname + .com
ProxyRequests Off
ProxyPreserveHost On
ProxyVia Full
<Proxy *>
Require all granted
</Proxy>
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:30000/
</VirtualHost>
5.禁用默认的 Apache 站点并启用新站点。
$ sudo a2dissite 000-default
$ sudo a2ensite example.com.conf
6.重新启动 Apache 服务器以应用更改
sudo systemctl restart apache2
此时我们可以准备好将 Apache 设置为反向代理,但我们还需要安装您项目的 npm 包,然后 运行 您的 NodeJS 应用程序。
7.其余步骤都与 NodeJS 部署有关。您可能已经知道这些步骤。
// install npm packages
npm install
// for a better experience using NodeJS in production install pm2 globally
npm install -g pm2
// Then run your NodeJS application using pm2 command
pm2 start // you should be at root of your NodeJS project folder when running this command
// run this another pm2 command to make sure your NodeJS app will re-run when it encounter downtime.
$ pm2 save
$ pm2 startup
您的 Apache 和 NodeJS 服务器已启动,现在 运行正在运行
尝试通过在浏览器地址栏中输入您的网站域名来访问您的网站
我正在尝试使用默认版本的 20.04 服务器 ubuntu 使用 apache 和节点工作的全新基于云的服务器。节点服务器似乎 运行 没有问题报告 4006 端口已打开。但是我相信我的 apache 配置不是。该请求将挂起很长时间。节点终端中没有显示任何错误。所以故障一定出在我的 apache 配置上,因为我们收到以下 apache 错误并且没有 JS 错误。
一段时间后请求错误
502 proxy error
Apache 错误日志
[Sun Oct 17 20:58:56.608793 2021] [proxy:error] [pid 1596878] (111)Connection refused: AH00957: HTTP: attempt to connect to [::1]:4006 (localhost) failed
[Sun Oct 17 20:58:56.608909 2021] [proxy_http:error] [pid 1596878] [client 207.46.13.93:27392] AH01114: HTTP: failed to make connection to backend: localhost
虚拟主机
<VirtualHost IP_ADDRESS:80>
ServerName api.aDomain.com
Redirect permanent / https://api.aDomain.com/
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost IP_ADDRESS:443>
ServerName api.aDomain.com
ProxyRequests on
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
ProxyPass / http://localhost:4006/
ProxyPassReverse / http://localhost:4006/
#certificates SSL
SSLEngine on
SSLCACertificateFile /etc/ssl/api.aDomain.com/apimini.ca
SSLCertificateFile /etc/ssl/api.aDomain.com/apimini.crt
SSLCertificateKeyFile /etc/ssl/api.aDomain.com/apimini.key
ErrorLog ${APACHE_LOG_DIR}/error_api.aDomain.com.log
CustomLog ${APACHE_LOG_DIR}/access_api.aDomain.com.log combined
</VirtualHost>
</IfModule>
终端输出
[nodemon] 1.19.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `babel-node -r dotenv/config --inspect=9229 index.js`
Debugger listening on ws://127.0.0.1:9229/c1fcf271-aea8-47ff-910e-fe5a91fce6d2
For help, see: https://nodejs.org/en/docs/inspector
Browserslist: caniuse-lite is outdated. Please run next command `npm update`
Server ready at http://localhost:4006
节点服务器
import cors from 'cors'
import scrape from './src/api/routes/scrape'
const express = require('express')
const { ApolloServer, gql } = require('apollo-server-express')
const { postgraphile } = require('postgraphile')
const ConnectionFilterPlugin = require('postgraphile-plugin-connection-filter')
const dbHost = process.env.DB_HOST
const dbPort = process.env.DB_PORT
const dbName = process.env.DB_NAME
const dbUser = process.env.DB_USER
const dbPwd = process.env.DB_PWD
const dbUrl = dbPwd
? `postgres://${dbUser}:${dbPwd}@${dbHost}:${dbPort}/${dbName}`
: `postgres://${dbHost}:${dbPort}/${dbName}`
var corsOptions = {
origin: '*',
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
}
async function main() {
// Construct a schema, using GraphQL schema language
const typeDefs = gql`
type Query {
hello: String
}
`
// Provide resolver functions for your schema fields
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
}
const server = new ApolloServer({ typeDefs, resolvers })
const app = express()
app.use(cors(corsOptions))
app.use(
postgraphile(process.env.DATABASE_URL || dbUrl, 'public', {
appendPlugins: [ConnectionFilterPlugin],
watchPg: true,
graphiql: true,
enhanceGraphiql: true,
})
)
server.applyMiddleware({ app })
//Scraping Tools
scrape(app)
const port = 4006
await app.listen({ port })
console.log(` Server ready at http://localhost:${port}`)
}
main().catch(e => {
console.error(e)
process.exit(1)
})
已启用 Apache 模组
/etc/apache2/mods-enabled/proxy.conf /etc/apache2/mods-enabled/proxy.load /etc/apache2/mods-enabled/proxy_http.load
更新错误日志
[Thu Oct 21 10:59:22.560608 2021] [proxy_http:error] [pid 10273] (70007)The timeout specified has expired: [client 93.115.195.232:8963] AH01102: error reading status line from remote server 127.0.0.1:4006, referer: https://miniatureawards.com/
[Thu Oct 21 10:59:22.560691 2021] [proxy:error] [pid 10273] [client 93.115.195.232:8963] AH00898: Error reading from remote server returned by /graphql, referer: https://miniatureawards.com/
如果您使用 docker 作为您的节点服务器,那么它可能设置不正确
我不是这方面的专家,但我有类似的设置;我使用 socket.io
来服务 WebSockets...
从你的帖子来看,你似乎也不需要代理 WebSockets,你日志中显示的似乎只是为了调试目的(如果我错了请纠正我)。
遵循我的 Apache 配置的核心:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:4006/ [P,L]
<Location />
ProxyPass http://127.0.0.1:4006/ retry=2
ProxyPassReverse http://127.0.0.1:4006/
</Location>
另外几个建议。
Warning
Do not enable proxying with
ProxyRequests
until you have secured your server. Open proxy servers are dangerous both to your network and to the Internet at large.
来源:https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxyrequests
我不知道您主机上的 IPV6 设置是什么,您可以尝试在 Apache 配置中使用 127.0.0.1
而不是 localhost
来尝试强制 Apache 使用 IPV4。
我无法准确预测到底发生了什么,它可能是 NodeJS 应用程序崩溃并且不再 运行ning 或者存在配置错误的 Apache 文件。但我坚信这种情况将通过从顶部做事来解决。
此步骤将通过更新 unbuntu 包、安装所需的应用程序、配置 Apache 文件以及使用 NodeJS 和 Apache 设置反向代理。
只是不要触摸您的 NodeJS 文件和其他与代码相关的应用程序,它们是安全的。您也可以备份以确保。该 ubuntu 服务器示例数据库应用程序上的其他 运行ning 应用程序如 MySQL
一样会很好并且仍然是 运行ning.
1.首先我们需要更新 ubuntu 包并安装 Apache 和 NodeJS
$ sudo apt update
$ sudo apt install apache2 npm
2。 运行 这个命令使我们能够使用 Apache 作为反向代理服务器
sudo a2enmod proxy proxy_http rewrite headers expires
3。创建 Apache 虚拟主机文件。
此命令将允许您使用 ubuntu 终端作为文本编辑器,按照终端的指南和提示进行编写。
注意:
将“yourSite.com”更改为您网站的域。文件名应该不是真正重要的。但我认为最好以您的站点域名命名,这样您就可以识别它。
$ sudo nano /etc/apache2/sites-available/yourSite.com.conf
4.使用 nano 编辑器是为您的站点编写 Apache 配置文件。
注意:这部分很关键,请注意
将您的 ServerName 和 ServerAlias 更改为您的站点域名。
ProxyPass 和 ProxyPassReverse 这个有两个参数。
第一个是反斜杠“/” 这是您的 NodeJS 应该位于的绝对路径,因为它的单个反斜杠表示它是您的主目录。
第二个是您的 NodeJS 应用程序的 url“http://127.0.0.1:3000/”。注意它的端口“3000”,您可能需要将其替换为您在 NodeJS 应用程序中使用的端口。
<VirtualHost *:80>
ServerName example.com // replace this with site domain name without www at the beginning
ServerAlias www.example.com // replace this with site domain name beginning with www. + yourdomainname + .com
ProxyRequests Off
ProxyPreserveHost On
ProxyVia Full
<Proxy *>
Require all granted
</Proxy>
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:30000/
</VirtualHost>
5.禁用默认的 Apache 站点并启用新站点。
$ sudo a2dissite 000-default
$ sudo a2ensite example.com.conf
6.重新启动 Apache 服务器以应用更改
sudo systemctl restart apache2
此时我们可以准备好将 Apache 设置为反向代理,但我们还需要安装您项目的 npm 包,然后 运行 您的 NodeJS 应用程序。
7.其余步骤都与 NodeJS 部署有关。您可能已经知道这些步骤。
// install npm packages
npm install
// for a better experience using NodeJS in production install pm2 globally
npm install -g pm2
// Then run your NodeJS application using pm2 command
pm2 start // you should be at root of your NodeJS project folder when running this command
// run this another pm2 command to make sure your NodeJS app will re-run when it encounter downtime.
$ pm2 save
$ pm2 startup
您的 Apache 和 NodeJS 服务器已启动,现在 运行正在运行
尝试通过在浏览器地址栏中输入您的网站域名来访问您的网站