当前位置: 首页 > news >正文

.Net Core微服务入门系列(一)——项目搭建

系列文章目录

1、.Net Core微服务入门系列(一)——项目搭建
2、.Net Core微服务入门全纪录(二)——Consul-服务注册与发现(上)
3、.Net Core微服务入门全纪录(三)——Consul-服务注册与发现(下)
4、.Net Core微服务入门全纪录(四)——Ocelot-API网关(上)
5、.Net Core微服务入门全纪录(五)——Ocelot-API网关(下)
6、.Net Core微服务入门全纪录(六)——EventBus-事件总线
7、.Net Core微服务入门全纪录(八)——Docker Compose与容器网络


在这里插入图片描述


前言📃

关于 微服务 的概念解释网上有很多, 个人理解微服务是一种系统架构模式,它和语言无关,和框架无关,和工具无关,和服务器环境无关。

微服务思想 是将传统的单体系统按照业务拆分成多个职责单一、且可独立运行的接口服务。至于服务如何拆分,没有明确的定义。几乎任何后端语言都能做微服务开发。微服务也并不是完美无缺的,微服务架构会带来更多的问题,增加系统的复杂度,引入更多的技术栈。


一、创建项目

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
一个客户端,一个产品服务,一个订单服务。3个项目都是 asp.net core web 应用程序。创建项目的时候记得启用一下 Docker 支持,或者后面添加也行。

为产品、订单服务添加一些基础代码,就简单的返回一下 服务名称,当前时间,服务的ip、端口。

在这里插入图片描述
在这里插入图片描述

二、在Docker中运行服务

为了方便,我使用 Docker 来运行服务,不用 Docker 也行,关于 docker 的安装及基本使用就不介绍了。

2.1 build镜像

在项目根目录打开 PowerShell 窗口执行:

docker build -t productapi -f ./Product.API/Dockerfile .

在这里插入图片描述
在这里插入图片描述
🔖提示:Successfully代表 build 成功了。

2.2 运行容器

执行:

docker run -d -p 9050:80 --name productservice productapi

在这里插入图片描述
执行:docker ps 查看运行的容器:
在这里插入图片描述
没问题,使用浏览器访问一下接口:
在这里插入图片描述
也没问题,其中的 ip 端口是 Docker 容器内部的 ip 端口,所以端口是80,这个无所谓。

产品服务部署好了,下面部署一下订单服务,也是同样的流程,就把指令简单贴一下吧:
build镜像:

docker build -t orderapi -f ./Order.API/Dockerfile .

运行容器:

docker run -d -p 9060:80 --name orderservice orderapi

在这里插入图片描述
OK,订单服务也部署完成了。

三、客户端调用

客户端我这里只做了一个web客户端,实际可能是各种业务系统、什么PC端、手机端、小程序。。。这个明白就好,为了简单就不搞那么多了。

因为客户端需要 http 请求服务端接口,所以需要一个 http 请求客户端,我个人比较习惯 RestSharp,安利一波:https://github.com/restsharp/RestSharp

在这里插入图片描述
添加基础代码:

在这里插入图片描述
IServiceHelper.cs:

    public interface IServiceHelper{/// <summary>/// 获取产品数据/// </summary>/// <returns></returns>Task<string> GetProduct();/// <summary>/// 获取订单数据/// </summary>/// <returns></returns>Task<string> GetOrder();}

ServiceHelper.cs:

    public class ServiceHelper : IServiceHelper{public async Task<string> GetOrder(){string serviceUrl = "http://localhost:9060";//订单服务的地址,可以放在配置文件或者数据库等等...var Client = new RestClient(serviceUrl);var request = new RestRequest("/orders", Method.GET);var response = await Client.ExecuteAsync(request);return response.Content;}public async Task<string> GetProduct(){string serviceUrl = "http://localhost:9050";//产品服务的地址,可以放在配置文件或者数据库等等...var Client = new RestClient(serviceUrl);var request = new RestRequest("/products", Method.GET);var response = await Client.ExecuteAsync(request);return response.Content;}}

Startup.cs:

    public class Startup{public Startup(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }// This method gets called by the runtime. Use this method to add services to the container.public void ConfigureServices(IServiceCollection services){services.AddControllersWithViews();//注入IServiceHelperservices.AddSingleton<IServiceHelper, ServiceHelper>();}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Home/Error");}app.UseStaticFiles();app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllerRoute(name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");});}}

HomeController.cs:

    public class HomeController : Controller{private readonly ILogger<HomeController> _logger;private readonly IServiceHelper _serviceHelper;public HomeController(ILogger<HomeController> logger, IServiceHelper serviceHelper){_logger = logger;_serviceHelper = serviceHelper;}public async Task<IActionResult> Index(){ViewBag.OrderData = await _serviceHelper.GetOrder();ViewBag.ProductData = await _serviceHelper.GetProduct();return View();}public IActionResult Privacy(){return View();}[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]public IActionResult Error(){return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });}}

Index.cshtml:

@{ViewData["Title"] = "Home Page";
}<div class="text-center"><h1 class="display-4">Welcome</h1><p>@ViewBag.OrderData</p><p>@ViewBag.ProductData</p>
</div>

代码比较简单,这里就不用 docker 了,直接控制台启动,使用浏览器访问:

在这里插入图片描述
一切正常。进行到这里,各个服务也独立运行了,客户端也能正常调用了,貌似算是完成一个简易的微服务了。但是,微服务架构最重要的原则就是——“高可用”。以上的做法明显不能满足高可用性,因为任何一个服务挂掉,所有依赖这个服务的业务系统都会受影响。

停止一下订单服务:

docker stop orderservice

在这里插入图片描述
在这里插入图片描述
订单服务停止,导致客户端业务系统无法获取订单数据。要解决这个问题,很容易想到:集群。

四、简单的服务集群

既然单个服务实例有挂掉的风险,那么部署多个服务实例就好了嘛,只要大家不同时全挂就行。

使用 docker 运行多个服务实例:

docker run -d -p 9061:80 --name orderservice1 orderapi
docker run -d -p 9062:80 --name orderservice2 orderapi
docker run -d -p 9051:80 --name productservice1 productapi
docker run -d -p 9052:80 --name productservice2 productapi

现在订单服务和产品服务都增加到3个服务实例。

那么稍微改造一下客户端代码吧:ServiceHelper.cs

public class ServiceHelper : IServiceHelper{public async Task<string> GetOrder(){string[] serviceUrls = { "http://localhost:9060", "http://localhost:9061", "http://localhost:9062" };//订单服务的地址,可以放在配置文件或者数据库等等...//每次随机访问一个服务实例var Client = new RestClient(serviceUrls[new Random().Next(0, 3)]);var request = new RestRequest("/orders", Method.GET);var response = await Client.ExecuteAsync(request);return response.Content;}public async Task<string> GetProduct(){string[] serviceUrls = { "http://localhost:9050", "http://localhost:9051", "http://localhost:9052" };//产品服务的地址,可以放在配置文件或者数据库等等...//每次随机访问一个服务实例var Client = new RestClient(serviceUrls[new Random().Next(0, 3)]);var request = new RestRequest("/products", Method.GET);var response = await Client.ExecuteAsync(request);return response.Content;}}

当然拿到这些服务地址可以自己做复杂的负载均衡策略,比如轮询,随机,权重等等 都行,甚至在中间弄个 nginx 也可以。这些不是重点,所以就简单做一个随机吧,每次请求来了随便访问一个服务实例。

浏览器测试一下:
在这里插入图片描述
可以看到请求被随机分配了。但是这种做法依然不安全,如果随机访问到的实例刚好挂掉,那么业务系统依然会出问题。简单处理思路是:1.如果某个地址请求失败了,那么换一个地址接着执行。2.如果某个地址的请求连续多次失败了,那么就移除这个地址,下次就不会访问到它了。。。。。。。业务系统实现以上逻辑,基本上风险就很低了,也算是大大增加了系统可用性了。

🤔然后思考另一个问题:

实际应用中,上层的业务系统可能非常多,为了保证可用性,每个业务系统都去考虑服务实例挂没挂掉吗?而且实际应用中服务实例的数量或者地址大多是不固定的,例如双十一来了,流量大了,增加了一堆服务实例,这时候每个业务系统再去配置文件里配置一下这些地址吗?双十一过了又去把配置删掉吗?显然是不现实的,服务必须要做到可灵活伸缩。

这时候就引入一个名词:服务注册与发现,下一篇介绍。

相关文章:

.Net Core微服务入门系列(一)——项目搭建

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…...

WPF 实现可视化操作数据库的程序全解析

在软件开发中&#xff0c;实现对数据库的可视化操作能极大提升开发效率和用户体验。借助 WPF&#xff08;Windows Presentation Foundation&#xff09;强大的界面开发能力&#xff0c;我们可以打造出功能丰富、交互友好的数据库操作程序。本文将详细介绍如何使用 WPF 搭建一个…...

python mysql库的三个库mysqlclient mysql-connector-python pymysql如何选择,他们之间的区别

三者的区别 1. mysqlclient 特点&#xff1a; 是一个用于Python的MySQL数据库驱动程序&#xff0c;用于与MySQL数据库进行交互。 依赖于MySQL的本地库&#xff0c;因此在安装时需要确保系统上已安装了必要的依赖项&#xff0c;如libmysqlclient-dev等。 性能较好&#xff0c…...

如何将数据库字符集改为中文,让今后所有的数据库都支持中文

最后一行有我自己的my.ini文件 数据库输入中文数据时会变为乱码&#xff0c; 这个时候&#xff0c;我们为每个数据库设置字符集&#xff0c;太过于麻烦&#xff0c;为数据库单独设置重启后又会消失 Set character_set_database’utf8’; Set character_set_server’utf8’; …...

Low-Level 大一统:如何使用Diffusion Models完成视频超分、去雨、去雾、降噪等所有Low-Level 任务?

Diffusion Models专栏文章汇总:入门与实战 前言:视频在传输过程中常常因为各种因素(如恶劣天气、噪声、压缩和传感器分辨率限制)而出现质量下降,这会严重影响计算机视觉任务(如目标检测和视频监控)的性能。现有的视频修复方法虽然取得了一些进展,但通常只能针对特定的退…...

EAMM: 通过基于音频的情感感知运动模型实现的一次性情感对话人脸合成

EAMM: 通过基于音频的情感感知运动模型实现的一次性情感对话人脸合成 1所有的材料都可以在EAMM: One-Shot Emotional Talking Face via Audio-Based Emotion-Aware Motion Model网站上找到。 摘要 尽管音频驱动的对话人脸生成技术已取得显著进展&#xff0c;但现有方法要么忽…...

Docker Compose的使用

文章首发于我的博客&#xff1a;https://blog.liuzijian.com/post/docker-compose.html 目录 Docker Compose是什么Docker Compose安装Docker Compose文件Docker Compose常用命令案例&#xff1a;部署WordPress博客系统 Docker Compose是什么 Docker Compose是Docker官方的开源…...

[STM32 HAL库]串口空闲中断+DMA接收不定长数据

一、空闲中断 STM32的串口具有空闲中断&#xff0c;什么叫做空闲呢&#xff1f;如何触发空闲中断呢&#xff1f; 空闲&#xff1a;串口发送的两个字符之间间隔非常短&#xff0c;所以在两个字符之间不叫空闲。空闲的定义是总线上在一个字节的时间内没有再接收到数据。触发条件…...

三、华为交换机 Hybrid

一、Hybrid功能 Hybrid口既可以连接普通终端的接入链路&#xff08;类似于Access接口&#xff09;&#xff0c;又可以连接交换机间的干道链路&#xff08;类似于Trunk接口&#xff09;。它允许多个VLAN的帧通过&#xff0c;并可以在出接口方向将某些VLAN帧的标签剥掉&#xff0…...

如何通过 Apache Airflow 将数据导入 Elasticsearch

作者&#xff1a;来自 Elastic Andre Luiz 了解如何通过 Apache Airflow 将数据导入 Elasticsearch。 Apache Airflow Apache Airflow 是一个旨在创建、安排&#xff08;schedule&#xff09;和监控工作流的平台。它用于编排 ETL&#xff08;Extract-Transform-Load&#xff0…...

Android Studio:Linux环境下安装与配置

更多内容&#xff1a;XiaoJ的知识星球 Android Studio&#xff1a;Linux环境下安装与配置 1.安装JDK2.安装Android Studio2.1 获取安装包2.2 安装&#xff08;1&#xff09;配置环境变量&#xff1a;&#xff08;2&#xff09;运行安装&#xff1a;&#xff08;3&#xff09;配…...

token是用来鉴权的,那session是用来干什么的?

在Web应用和API设计中&#xff0c;鉴权与会话管理是两个核心概念&#xff0c;它们对于确保用户身份的安全性和维护用户会话状态至关重要。Token和Session是两种常用的鉴权与会话管理机制&#xff0c;它们各自具有独特的工作原理和适用场景。下面是对Token和Session的详细解析及…...

基于 WEB 开发的二手车辆销售管理系统设计与实现

标题:基于 WEB 开发的二手车辆销售管理系统设计与实现 内容:1.摘要 摘要&#xff1a;随着互联网技术的不断发展&#xff0c;电子商务在各个领域得到了广泛的应用。本文以二手车辆销售管理系统为例&#xff0c;探讨了基于 WEB 开发的销售管理系统的设计与实现。通过对系统需求的…...

wordpress的火车头商品发布接口

<?php require ../wp-load.php; ini_set(memory_limit, 1024M); set_time_limit(180);$top_cat ; # 图片链接域名替换 $image_host ;$start_time microtime(true);$counter 0; // 临时缓存 $products $skus $categories []; $var_sku_index 1;$rowData$_POST;// if…...

浙江安吉成新照明电器:Acrel-1000DP 分布式光伏监控系统应用探索

安科瑞吕梦怡 18706162527 摘 要&#xff1a;分布式光伏发电站是指将光伏发电组件安装在用户的建筑物屋顶、空地或其他适合的场地上&#xff0c;利用太阳能进行发电的一种可再生能源利用方式&#xff0c;与传统的大型集中式光伏电站相比&#xff0c;分布式光伏发电具有更灵活…...

总结3..

#include<stdio.h> int n,m; int a[1002][1002]; int b[1002][1002];//判断该空的八连通图是否被走过 int gg0; int dd0; int xz[8]{-1,-1,-1,0,0,1,1,1},yz[8]{-1,0,1,-1,1,-1,0,1};//八个方向 void dfs(int x,int y) { int dx,dy; for(int i0;i<8;i) { …...

信息奥赛一本通 1168:大整数加法

这道题是一道大整数加法&#xff0c;涉及到高精度的算法&#xff0c;比如说有两个数要进行相加&#xff0c;1111111111111111111111111111111111111112222222222222222222222222222222&#xff0c;那么如果这两个数很大的话我们常用的数据类型是不能进行计算的&#xff0c;那么…...

3.3 OpenAI GPT-4, GPT-3.5, GPT-3 模型调用:开发者指南

OpenAI GPT-4, GPT-3.5, GPT-3 模型调用:开发者指南 OpenAI 的 GPT 系列语言模型,包括 GPT-4、GPT-3.5 和 GPT-3,已经成为自然语言处理领域的标杆。无论是文本生成、对话系统,还是自动化任务,开发者都可以通过 API 调用这些强大的模型来增强他们的应用。本文将为您详细介…...

横盘出击的三种经典走势形态,买点以及需要注意的问题技术详解

龙头股在横盘整理过程中&#xff0c;也会出现几种不同的形态&#xff0c;比如矩形整理形态&#xff0c;或者在某一趋势线下方运行。 第一种形态&#xff1a;突破横盘趋势线 突破横盘趋势线时识别横盘龙头启动的关键点位。股价经过一段时间的横盘后&#xff0c;突然出现快速上…...

处理没有提示的字符串、计算相隔天数应用题

正常情况下&#xff0c;小云每天跑 1 千米。如果某天是周一或者月初&#xff08;1 日&#xff09;&#xff0c;为了激励自己&#xff0c;小云要跑 2 千米。如果同时是周一或月初&#xff0c;小云也是跑 2 千米。 小云跑步已经坚持了很长时间&#xff0c;从 1990 年 1 月 1 日周…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...