当前位置:   article > 正文

.netcore微服务——项目搭建

.netcore微服务——项目搭建

在.NET Core中,微服务是一种架构风格,它将应用程序构造为一组小型服务的集合,这些服务都通过HTTP-based API进行通信。每个服务都是独立部署的,可以用不同的编程语言编写,并且可以使用不同的数据存储技术。

微服务的主要优点包括:

  • 增强容错能力:一个服务的故障不会影响其他服务。

  • 增强弹性:可以根据需求增加或减少服务的实例。

  • 增加弹性:使用更适合的语言或工具。

  • 增加敏捷性:每个服务都可以独立于其他服务进行更新和迭代。

以下是一个简单的例子,展示如何在.NET Core中创建一个简单的微服务。

首先,创建一个ASP.NET Core Web 项目作为客户端,两个ASP.NET Core Web API项目作为服务(产品服务和订单服务),添加docker支持,为产品、订单服务添加一些基础代码,就简单的返回一下 服务名称,当前时间,服务的ip、端口

在Docker中运行服务

安装docker客户端

点击启用或关闭 windows 功能,然后勾选上 Hyper-V 以及适用于 Linux 的 Windows 子系统

 安装完客户端后报错:You are trying to start Docker Desktop but you don't have enough memory. Free some memory or change your settings.这是内存不足导致,可以修改docker的配置文件

 在项目根目录打开PowerShell窗口执行:docker build -t productapi -f ./Product.API/Dockerfile .

 运行容器:执行:docker run -d -p 9050:80 --name productservice productapi

查看运行的容器: 执行:docker ps

 产品服务部署成功。

 产品服务部署好了,下面部署一下订单服务,也是同样的流程:

build镜像:docker build -t orderapi -f ./Order.API/Dockerfile .
运行容器:docker run -d -p 9060:80 --name orderservice orderapi

 订单服务也部署完成了。

 在客户端调用

 客户端新建一个web用来测试,客户端需要http请求服务端接口,所以需要一个http请求客户端,这里使用RestSharp

 新建接口和实现IProductService.cs,IOrderService,ProductService,OrderService,并在program.cs里注入服务。

  1. namespace ProjectCore.MVC.Services
  2. {
  3. public interface IOrderService
  4. {
  5. /// <summary>
  6. /// 获取产品数据
  7. /// </summary>
  8. /// <returns></returns>
  9. Task<string> GetOrders();
  10. }
  11. }
  1. namespace ProjectCore.MVC.Services
  2. {
  3. public interface IProductService
  4. {
  5. /// <summary>
  6. /// 获取产品数据
  7. /// </summary>
  8. /// <returns></returns>
  9. Task<string> GetProducts();
  10. }
  11. }
  1. using RestSharp;
  2. namespace ProjectCore.MVC.Services
  3. {
  4. public class OrderService : IOrderService
  5. {
  6. public async Task<string> GetOrders()
  7. {
  8. string serviceUrl = "http://localhost:9060";
  9. var Client = new RestClient(serviceUrl);
  10. var request = new RestRequest("/api/order", Method.Get);
  11. var reponse = await Client.ExecuteAsync(request);
  12. return reponse.Content;
  13. }
  14. }
  15. }
  1. using RestSharp;
  2. namespace ProjectCore.MVC.Services
  3. {
  4. public class ProductService : IProductService
  5. {
  6. public async Task<string> GetProducts()
  7. {
  8. string serviceUrl = "http://localhost:9050";
  9. var Client = new RestClient(serviceUrl);
  10. var request = new RestRequest("/api/product", Method.Get);
  11. var reponse = await Client.ExecuteAsync(request);
  12. return reponse.Content;
  13. }
  14. }
  15. }
  1. builder.Services.AddSingleton<IProductService, ProductService>();
  2. builder.Services.AddSingleton<IOrderService, OrderService>();
  1. //HomeController.cs
  2. using Microsoft.AspNetCore.Mvc;
  3. using ProjectCore.MVC.Models;
  4. using ProjectCore.MVC.Services;
  5. using System.Diagnostics;
  6. namespace ProjectCore.MVC.Controllers
  7. {
  8. public class HomeController : Controller
  9. {
  10. private readonly ILogger<HomeController> _logger;
  11. private readonly IProductService _productService;
  12. private readonly IOrderService _orderService;
  13. public HomeController(ILogger<HomeController> logger, IProductService productService, IOrderService orderService)
  14. {
  15. _logger = logger;
  16. _productService = productService;
  17. _orderService = orderService;
  18. }
  19. public async Task<IActionResult> Index()
  20. {
  21. ViewBag.OrderData = await _orderService.GetOrders();
  22. ViewBag.ProductData = await _productService.GetProducts();
  23. return View();
  24. }
  25. public IActionResult Privacy()
  26. {
  27. return View();
  28. }
  29. [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
  30. public IActionResult Error()
  31. {
  32. return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
  33. }
  34. }
  35. }
  1. //Index.cshtml
  2. @{
  3. ViewData["Title"] = "Home Page";
  4. }
  5. <div class="text-center">
  6. <h1 class="display-4">Welcome</h1>
  7. <p>
  8. @ViewBag.OrderData
  9. </p>
  10. <p>
  11. @ViewBag.ProductData
  12. </p>
  13. </div>

 F5启动项目:

 将订单服务停止:

 客户端无法获取订单数据了。

这样可以通过简单的集群来解决,部署多个订单实例

  1. docker run -d -p 9061:80 --name orderservice1 orderapi
  2. docker run -d -p 9062:80 --name orderservice2 orderapi
  3. docker run -d -p 9051:80 --name productservice1 productapi
  4. docker run -d -p 9052:80 --name productservice2 productapi

 然后客户端中做个随机访问服务实例:

  1. using RestSharp;
  2. namespace ProjectCore.MVC.Services
  3. {
  4. public class ProductService : IProductService
  5. {
  6. public async Task<string> GetProducts()
  7. {
  8. string[] serviceUrl = { "http://localhost:9050","http://localhost:9051", "http://localhost:9052" };
  9. var Client = new RestClient(serviceUrl[new Random().Next(0, 3)]);
  10. var request = new RestRequest("/api/product", Method.Get);
  11. var reponse = await Client.ExecuteAsync(request);
  12. return reponse.Content;
  13. }
  14. }
  15. }
  1. using RestSharp;
  2. namespace ProjectCore.MVC.Services
  3. {
  4. public class OrderService : IOrderService
  5. {
  6. public async Task<string> GetOrders()
  7. {
  8. string[] serviceUrl = { "http://localhost:9060", "http://localhost:9061", "http://localhost:9062" };
  9. //随机访问一个实例
  10. var Client = new RestClient(serviceUrl[new Random().Next(0, 3)]);
  11. var request = new RestRequest("/api/order", Method.Get);
  12. var reponse = await Client.ExecuteAsync(request);
  13. return reponse.Content;
  14. }
  15. }
  16. }

 但是这样也会存在一个问题,如果正好随机到停止的服务就会导致客户端读不到数据。所以将使用Consul来进行服务的注册与发现。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号