🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1792閲覧

AWS Mysql webサーバー(apache)からDBサーバーにCRUDできない。

webnakada

総合スコア7

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2020/12/31 07:23

編集2021/01/01 11:19

#困っていること
AWSのEC2でwebサーバー(apache)から、異なるサブネット上にmysqlをインストールしたDBサーバー対して、データ登録や取得が成功しません。
問題点など教えていただければ幸いでございます。2020年中に解消したいです...皆様どうかお願いいたします!

#エラー
下記エラーがchromeのコンソールに表示されています。

①下記のフロントエンドのソースコードの17行目で発生 Error: Network Error at e.exports (createError.js:16) at XMLHttpRequest.p.onerror (xhr.js:84)
 ②こちらのエラーはyu_1985さんのご回答より解決しました。ありがとうございました。 xhr.js:177 GET http://localhost:9000/api/get net::ERR_CONNECTION_REFUSED
 ③新しいエラー(2021/1/1追記) net::ERR_CONNECTION_TIMED_OUT

#環境、コード
●サーバーOS: amazon linux2

●フロントエンド
webサーバーの/var/www/htmlにyarn buildしたコードを配置。ブラウザからwebサーバーにアクセスするとUIが表示される状態。

import React,{useState,useEffect} from 'react'; import AxiosBase from 'axios'; import { Link } from 'react-router-dom'; import { useForm } from 'react-hook-form'; import TodoList from './todoList'; const InputForm = () => { const Axios = AxiosBase.create({ baseURL:"http://ec2-13-115-56-254.ap-northeast-1.compute.amazonaws.com:9000", header:{'X-Requested-With': 'XMLHttpRequest'} }) const {register,handleSubmit,reset} = useForm(); const [todoList,setTodoList] = useState([]); const [newTask,setNewTask] = useState([]); useEffect(() => { Axios.get('/api/get') .then((response) =>{ setTodoList(response.data) }) .catch((err) => console.log(err)); },[newTask.length]) const onSubmit = async (data) => { const {task} = data; setNewTask([ ...newTask, task ]); Axios.post('/api/insert',{ task:task, }).then((result) => console.log('成功')) .catch((err)=>console.log(err)); reset(); } return( <> <Link to='/'>Home</Link> <form onSubmit={handleSubmit(onSubmit)}> <input type="text" name='task' ref={register}/> <button>追加</button> </form> <TodoList todoList={todoList}/> </> ) } export default InputForm;
"@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", "axios": "^0.21.1", "react": "^17.0.1", "react-dom": "^17.0.1", "react-hook-form": "^6.13.1", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "react-scripts": "4.0.1", "web-vitals": "^0.2.4"

●バックエンド
expressで構築。

const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const path = require('path'); const mysql = require('mysql'); const app = express(); app.use(express.static(path.join(__dirname,'build'))); app.get('/*',(req,res) => { res.sendFile(path.join(__dirname,'build','index.html')); }); const db = mysql.createPool({ host:'ip-10-0-24-237.ap-northeast-1.compute.internal', user:'guestuser', password:'**********', database:'todolist' }) app.use(cors()); app.use(express.json()); app.use(bodyParser.urlencoded({extended: true})); app.post('/api/insert', (req, res) => { const task = req.body.task; console.log(req.body); const sqlInsert = "INSERT INTO tasks (task) VALUES (?);"; db.query(sqlInsert,[task],(err,result) => { console.log('insert success'); }) }) app.get('/api/get',(req,res) => { const sqlSelect = 'SELECT * FROM tasks;'; db.query(sqlSelect,(err,result) => { res.send(result); }) }) app.delete('/api/delete/:id',(req,res) => { const id = req.params.id; const sqlDelete = 'DELETE FROM tasks WHERE id = ?;' db.query(sqlDelete,[id],(err,result) => { if (err) console.log(err); }) }) app.listen(9000,() => { console.log(`port 9000`) });

#試したこと、確認したこと
・上記バックエンドのcreatePoolで、hostにDBサーバーのdns名を指定。
ちなみに、ローカルの開発環境ではhostにlocalhost、userにrootを指定しており、データベースへのCRUDはうまくいっていました。

・DBサーバーのポート3306は開放できている。

$ sudo lsof -i -P COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 369 mysql 32u IPv6 57675 0t0 TCP *:33060 (LISTEN) mysqld 369 mysql 34u IPv6 57680 0t0 TCP *:3306 (LISTEN)

・自宅のネットワーク環境は問題なし
・webサーバー間の通信も問題なし。pingにて確認。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yu_1985

2020/12/31 09:31

WEBサーバからDBサーバに対して、同じユーザでmysqlクライアントを使って接続できますか?
webnakada

2020/12/31 10:09

sudo mysql -u guestuser -h ip-10-0-24-237.ap-northeast-1.compute.internal -p webサーバー上で上記のコマンドを実行するとログインできます。
yu_1985

2020/12/31 21:44

よく見るとhttp://localhost:9000/api/get に対するアクセスがエラーになってますけど、WEBサーバのパブリックIPを使ってアクセスしてるにも関わらずそうなるということですか?
webnakada

2020/12/31 23:33

IPがパブリック、プライベートかどうかは気にしておりませんでした... ターミナルでは下記のような状態で、同一VPC内の別のサブネットにあるDBサーバーのmsqlにアクセスしにいっております。10.0.1.10はwebサーバーのプライベートIPです。 [ec2-user@ip-10-0-1-10 ~] $ sudo mysql -u guestuser -h ip-10-0-24-237.ap-northeast-1.compute.internal -p ちなみに、DBサーバーのmysqlのユーザー登録にて、guestuserのhostをwebサーバーのプライベートIPである10.0.1.10にしております。
yu_1985

2021/01/01 07:45

いや、そういうことではなく、WEBサーバにChromeでアクセスするときのURLの話です。 AWS内部でのアクセスについてはプライベートIPでOKです(というより、むしろそちらが推奨)
webnakada

2021/01/01 07:54

失礼いたしました。 chromeからwebサーバーにアクセスするときのURLはパブリックIPです。
guest

回答1

0

ベストアンサー

よくよく見たらここで

javascript

1useEffect(() => { 2 Axios.get('http://localhost:9000/api/get') 3 .then((response) =>{ 4 setTodoList(response.data) 5 }) 6 .catch((err) => console.log(err));   17行目 上記エラー発生箇所 7 },[newTask.length])

のように、localhostを対象にリクエストを送るようにしてるからではないでしょうか。
axiosにはどこかでBASE URLを指定するところがあったと思うので、ここでBASE URLを適切に指定した上でここで指定するのはパスでは?
JSはクライアント側で動くので、localhostを指定してしまうとサーバではなくクライアント側のlocalhostを参照してしまいます。

[axios] axios の導入と簡単な使い方

投稿2021/01/01 08:07

yu_1985

総合スコア7588

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

webnakada

2021/01/01 11:04

ご回答ありがとうございます! ご指摘の通り、リンク先のqiita記事を参考にBASEURLを指定したところ、ERR_CONNECTION_REFUSEDのエラーは解消されましたが、同じ箇所でnet::ERR_CONNECTION_TIMED_OUTのエラーが発生しました。 サーバーは稼働していますし、webサーバーからDBサーバーにpingコマンドを実施しても反応が返ってきます。もちろん自宅のネットワーク環境も問題ありません。 他に考えられる原因としてどんなことがあるか教えて頂ければ幸いです。 お手数おかけいたします。
yu_1985

2021/01/01 19:15 編集

BASE URLを指定するだけではなくて、Axios.get、Axios.put等々でURLをフルで指定している箇所を修正しなければならないと思うのですが…。 そちらは修正しましたか? また、pingコマンドはicmpなので、セキュリティグループでicmpを許可していなければ通りません。 そのためだけにicmpを許可する意味もさほどないと思っているので、pingでの疎通確認はあまりおすすめしません。 HTTPリクエストの疎通確認をしたいのにわざわざ別のプロトコルで送るのも違うと思いますし。
webnakada

2021/01/01 23:55

修正いたしました。質問文のコードが修正したものです。 pingの疎通確認に関してもご指摘ありがとうございます。 chromeの開発ツールで確認すると、net::ERR_CONNECTION_TIMED_OUTが:9000/api/getにでており、ターミナルにてcurl ドメイン名:9000のコマンドを実行するとconnection refusedになります。ここに問題はありそうでしょうか?
yu_1985

2021/01/02 13:50

ホスト名の具体的な値はマスクしてください。 > net::ERR_CONNECTION_TIMED_OUT 読み違いでなければrefusedでなくてtimed outに見えますが…。 これとは別ということですか? タイムアウトなら、セキュリティグループで9000番ポートを許可しているか確かめてください。
webnakada

2021/01/03 12:16

返信遅くなり申し訳ありません。 pcのターミナルではconnection refusedになっていました。(もしかしたらこちらの見間違えかもですが...) AWSのコンソールにて、セキュリティグループで9000番ポートを許可すると解消しました。 ただ、mysqlから返ってくるのが空配列となるので、もう1歩です...原因考えてみます。
webnakada

2021/01/03 14:31

データが取得できないのは、mysqlで認証方法が認めらていないことが原因でした。 下記の記事を参考にしたところ解決しました。 https://qiita.com/monga3/items/6583c07a9b275b469608 yu_1985さん長々とお付き合い頂き本当にありがとうございました!非常に助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問