用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: