起因:
以下の理由により、eureka の代わりに naocs が使用されます。
- 統合サービス登録および構成センター: Nacos は、サービス登録および構成管理を 1 つのプラットフォーム上で統合できる統合サービス登録および構成管理機能を提供します。これにより、システム アーキテクチャが簡素化され、依存するコンポーネントの数が減ります。
-
動的構成管理: Nacos は、アプリケーションの再起動や再デプロイを行わずに構成情報をリアルタイムで変更し、サービス インスタンスに通知できる動的構成管理機能を提供します。これにより、システム構成の更新がより便利かつ効率的に行われます。
-
複数のレジストリ モードのサポート: Nacos は、DNS ベースのサービス ディスカバリや RPC ベースのサービス ディスカバリなどの複数のレジストリ モードをサポートします。これにより、Nacos はさまざまなネットワーク環境やアプリケーション シナリオにおいてより柔軟になります。
-
コミュニティ活動と開発傾向: Nacos は Alibaba によるオープンソース プロジェクトであり、オープンソース コミュニティで広範な注目と貢献を受けています。積極的なコミュニティサポートと急速な開発傾向があります。
プロジェクト構成
- docker-compose を使用して 2 つの v2.2.0 nacos コンテナが 1 つのインスタンス上で起動されました
- springboot プロジェクトでは、バージョン 2.2.0 の nacos 依存関係が導入されています。
- nginx プロキシは 2 つの nacos ポートの転送負荷を実行します
プロセス
プロジェクトエラーログ:
ERROR o.s.boot.SpringApplication.reportFailure(SpringApplication.java:826) - Application run failed
java.lang.reflect.UndeclaredThrowableException: null
at org.springframework.util.ReflectionUtils.rethrowRuntimeException(ReflectionUtils.java:147)
at com.alibaba.cloud.nacos.registry.NacosServiceRegistry.register(NacosServiceRegistry.java:73)
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.register(AbstractAutoServiceRegistration.java:239)
at com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration.register(NacosAutoServiceRegistration.java:76)
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.start(AbstractAutoServiceRegistration.java:138)
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.bind(AbstractAutoServiceRegistration.java:101)
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.onApplicationEvent(AbstractAutoServiceRegistration.java:88)
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.onApplicationEvent(AbstractAutoServiceRegistration.java:47)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:403)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:360)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:165)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at net.novelcomic.server.author.NcAuthorApplication.main(NcAuthorApplication.java:95)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52)
Caused by: com.alibaba.nacos.api.exception.NacosException: failed to req API:/api//nacos/v1/ns/instance after all servers([172.25.151.166:8848]) tried: <html><body><h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div id='created'>Thu Jun 15 09:10:16 CST 2023</div><div>There was an unexpected error (type=Bad Request, status=400).</div><div>receive invalid redirect request from peer 172.19.0.2</div></body></html>
at com.alibaba.nacos.client.naming.net.NamingProxy.reqAPI(NamingProxy.java:496)
at com.alibaba.nacos.client.naming.net.NamingProxy.reqAPI(NamingProxy.java:401)
at com.alibaba.nacos.client.naming.net.NamingProxy.reqAPI(NamingProxy.java:397)
at com.alibaba.nacos.client.naming.net.NamingProxy.registerService(NamingProxy.java:212)
at com.alibaba.nacos.client.naming.NacosNamingService.registerInstance(NacosNamingService.java:207)
at com.alibaba.cloud.nacos.registry.NacosServiceRegistry.register(NacosServiceRegistry.java:64)
... 26 common frames omitted
- nacos /api//nacos/v1/ns/instance にアクセスするインターフェースがエラーを報告する問題が発生しており、理由は以下の通りです。
-
Nacos レジストリ インスタンスの構成が正しくないか、アクセスできません。
curl
コマンドまたはブラウザでアドレスにアクセスして、正常にアクセスできるかどうかを確認してください。 -
Nacos 登録センターのパス構成が正しくありません。Spring プロジェクトの Nacos の構成項目をチェックして、
server-addr
構成が Nacos インスタンスのアドレスとポートを正しく指していることを確認してください。 -
Nacos レジストリのバージョンは Spring プロジェクトと互換性がありません。使用する Nacos バージョンが Spring Cloud バージョンと互換性があることを確認してください。Nacos バージョンのアップグレードまたはダウングレードを試行したり、関連ドキュメントをチェックして互換性を確認したりできます。
・2と3は問題ないことを確認しましたが、問題は1です。
[root@MT01 nc-author-service]# curl http://172.25.151.166:8848/nacos/v1/ns/instance?serviceName=nc-author-service
caused: Param 'ip' is required.
このインターフェイスはサービス インスタンス情報を Nacos サービス レジストリに登録するために使用されるため、インターフェイスにアクセスするときは/nacos/v1/ns/instance
パラメーターを指定する必要がありますip
。ip
パラメーターは、登録されたサービス インスタンスの IP アドレスを指定します。
ただし、私は新しいバージョンの nacos v2.x を使用しています。
Nacos の古いバージョン (v1.x バージョンなど) では、ip
登録するインスタンスの IP アドレスを識別するためにパラメーターが使用されるため、このパラメーターは必須です。パラメータが指定されていない場合はip
、「Param 'ip' が必要です。」のようなエラーが表示されます。
しかし、新しいバージョン (v2.x バージョンなど) では、Nacos に IP アドレスを自動的に取得する機能が導入され、パラメーターを指定しなくてもip
インスタンスを正しく登録できるようになります。Nacos はサーバーのネットワーク構成に従って IP アドレスを自動的に取得し、それを登録に使用します。このようにして、インターフェイスにアクセスするときにパラメータを/nacos/v1/ns/instance
手動で運ぶ必要がなくなりました。ip
問題はここにあります!!!
dockerで起動したnacosを使用するため、ipはコンテナ内のipなので登録できませんが、コンテナ内のipにホストマシンのipを取得させるだけで済みます。
解決
-
IP アドレスの代わりにホスト名を使用する: サービス インスタンスを登録するときは、
ip
特定の IP アドレスの代わりにホスト名をパラメーターの値として使用します。このように、Nacos はホスト名を使用してサービス インスタンスのネットワーク アドレスを識別します。 -
IP アドレスの自動取得を構成する: 一部のフレームワークとコンポーネントは、手動で指定しなくてもローカル IP アドレスを自動的に取得し、Nacos に登録できます。たとえば、Spring Cloud では、指定されたネットワーク インターフェイスを無視して、利用可能な IP アドレスを自動的に取得して登録するように
spring-cloud-starter-alibaba-nacos-discovery
構成できます。spring.cloud.inetutils.ignored-interfaces
最初の解決策を使用して nacos を変更します。network_mode: host
同時にport_bindings
使用することはできません。ポートを削除する必要があります。
version: '3'
services:
nacos-node1:
image: nacos/nacos-server:v2.2.0
container_name: nacos-node1
environment:
- PREFER_HOST_MODE=hostname
- MODE=cluster
- NACOS_SERVERS=nacos-node1:8848,nacos-node2:8848
- JVM_XMS=512m
- JVM_XMX=1024m
- NACOS_SERVER_IP=你的私网ip
restart: always
volumes:
- /data/nacos/conf/application.properties:/home/nacos/conf/application.properties
- /data/nacos/logs/8847:/home/nacos/logs
network_mode: host
nacos-node2:
image: nacos/nacos-server:v2.2.0
container_name: nacos-node2
environment:
- PREFER_HOST_MODE=hostname
- MODE=cluster
- NACOS_SERVERS=nacos-node1:8848,nacos-node2:8848
- JVM_XMS=512m
- JVM_XMX=1024m
- NACOS_SERVER_IP=你的私网ip
restart: always
volumes:
- /data/nacos/conf/application1.properties:/home/nacos/conf/application.properties
- /data/nacos/logs/8849:/home/nacos/logs
network_mode: host