nacos實現Java和.NetCore的服務註冊和呼叫

2023-03-11 21:01:13

用nacos作為服務註冊中心,如何註冊.NetCore服務,如何在Java中呼叫.NetCore服務呢?可以分為下面幾個步驟:

  0.執行nacos

  1.開發.net core服務,然後呼叫nacos提供的.net core sdk註冊服務。

  2.開發Java服務,然後註冊服務。

  3.用RestTemplate呼叫.net core服務。

  4.用OpenFeign呼叫服務

 

  下面來看具體步驟:

  0.參考我之前的文章分散式設定nacos搭建踩坑指南(下) ,首先執行nacos.

 1.首先開發一個.net core web api,我們返回的資料是天氣預報訊息,新建一個WeatherForecastController,程式碼如下:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
​
namespace WebApi.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };
​
        private readonly ILogger<WeatherForecastController> _logger;
​
        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }
​
        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
        //public String Get()
        //{
        //    return "sunny";
        //}
​
    }
}

然後設定好存取的url,在launchSettings.json的修改 "applicationUrl": "http://192.168.1.110:5000",注意這裡去掉了https://192.168.1.110:5001,是為了避免在後面Java呼叫時需要證書的麻煩。

最後我們在cmd中輸入dotnet run,當服務正常執行起來後,在瀏覽器中輸入:http://192.168.1.110:5000/weatherforecast,發現成功返回天氣資料,格式為json,截圖如下:

2.net core專案中引入nuget包:nacos-sdk-csharp,截圖如下:

3.呼叫nacos-sdk-csharp,進行服務註冊,程式碼如下:

using System;
using Microsoft.Extensions.DependencyInjection;
using Nacos.V2;
using Nacos.V2.DependencyInjection;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace NacosDiscoveryProviderNetCoreTest1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string serverAddr = "http://localhost:8848";
            string dataId = "config2";
            string group = "DEFAULT_GROUP";
​
            IServiceCollection services = new ServiceCollection();
            //register service 
            services.AddNacosV2Naming(
                 x =>
                 {
                     x.ServerAddresses = new List<string>() { serverAddr };
                     //x.ConfigUseRpc = true;
​
                 }
                );
            IServiceProvider serviceProvider = services.BuildServiceProvider();
            var namingSvc = serviceProvider.GetService<INacosNamingService>();
            await namingSvc.RegisterInstance("weatherforecast", "192.168.1.110", 5000);
            Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(await namingSvc.GetAllInstances("weatherforecast")));
            Console.ReadKey();
​
​
        }
    }
}

我們進入nacos後臺,如果服務註冊成功,我們就會在服務列表中看到weatherforecast服務了,如下所示:

 

有兩個地方必須切記注意:

1).namingSvc.RegisterInstance("weatherforecast", "192.168.1.110", 5000);是一句很關鍵的程式碼,意思是註冊一個名為weatherforecast,地址為:192.168.1.110,埠為:5000的服務。

2)launchSettings.json裡的applicationUrl必須去掉包含https的設定,只保留http的設定,即只保留:"applicationUrl": "http://192.168.1.110:5000",否則在Java中呼叫會報證書錯誤。

 

4.參考nacos服務註冊,利用阿里巴巴Spring boot腳手架,引入:spring-boot-starter-web,spring-cloud-starter-alibaba-nacos-discovery,spring-cloud-starter,spring-boot-starter-test,spring-cloud-starter-loadbalancer,spring-cloud-starter-openfeign。完整的pom如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.11</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>nocos-discovery-consumer-sample</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nocos-discovery-consumer-sample</name>
    <description>Demo project for Spring Boot</description><properties>
        <java.version>1.8</java.version>
        <spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version>
        <spring-cloud.version>2021.0.4</spring-cloud.version>
    </properties><dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency><dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
          <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
          <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>
</dependency>
​
​
​
<dependency>
<groupId>org.netbeans.external</groupId>
<artifactId>org-apache-commons-httpclient</artifactId>
<version>RELEASE126</version>
</dependency>
​
​
    </dependencies><dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement><build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build></project>

5.application.properties的設定同前面的文章裡介紹的設定一樣,程式碼如下所示:

spring.application.name=nocos-discovery-consumer-sample
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
spring.cloud.nacos.discovery.server-addr=localhost:8848
spring.cloud.nacos.discovery.namespace=public
spring.main.allow-circular-references=true
server.port=9091

 

6.新建一個名為WeatherService的介面,程式碼如下:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
​
​
@FeignClient("weatherforecast") 
@LoadBalancerClient("weatherforecast")
public interface WeatherService {
​
  @GetMapping("/Weatherforecast")
  public String getWeather();
  
  
}

 

 7.新建一個RestTemplateController,程式碼如下:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
​
import com.alibaba.fastjson.JSONObject;
​
import org.springframework.context.annotation.Bean;
import org.apache.commons.httpclient.methods.GetMethod;
//import org.apache.http.client.HttpClient;
import org.apache.commons.httpclient.HttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import java.io.*;
​
​
​
@RestController
public class RestTemplateController {
​
   //@LoadBalanced
   @Autowired
   public RestTemplate resttemplate;
   
   //@LoadBalanced
   @Bean
   public RestTemplate restTemplate() {
     return new RestTemplate();
   }
   
   @Autowired
   private EchoService echoService;
   
   @Autowired
   private WeatherService weatherService;
   
   @Autowired DiscoveryClient discoveryClient;
   
   //resttemplate test
   @GetMapping("/call/echo") 
   public String callEcho() { 
     
     System.out.println("callEcho");
     
  
     ServiceInstance serviceInstance=discoveryClient.getInstances("weatherforecast").get(0);
     System.out.println("Host is: "+serviceInstance.getHost()+" ,port is: "+serviceInstance.getPort());
         String urlString=serviceInstance.getHost()+":"+serviceInstance.getPort()+"/weatherforecast";   
     urlString="http://"+urlString;     
     //RestTemplate test
     return resttemplate.getForObject(urlString, String.class);
     
   }
    
   //openFeign test
   @GetMapping("/getWeather")
   public String getWeather() {
     
     return weatherService.getWeather();
​
   }
}

其中要注意的幾點:

1) ServiceInstanceserviceInstance=discoveryClient.getInstances("weatherforecast").get(0);是一句關鍵的程式碼,用於獲取weatherforecast服務的範例。

2)callEcho()是呼叫RestTemplage存取netcore服務

3)getWeather是呼叫openFeiign存取netcore服務

 

8.啟動類程式碼如下:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
​
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
​
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class NocosDiscoveryConsumerSampleApplication {
​
    public static void main(String[] args) {
        SpringApplication.run(NocosDiscoveryConsumerSampleApplication.class, args);
    }
​
}

9.執行,存取http://192.168.1.110:5000/weatherforecast和http://localhost:9091/getWeather: