ABP微服務架構中網關層NullReferenceException問題解析與HTTP配置優化

ABP微服務架構中網關層NullReferenceException問題解析與HTTP配置優化

一、網關層System.NullReferenceException問題解析

1.1 問題現象與原因分析

在ABP微服務架構開發過程中,網關層啟動后調用微服務接口時出現以下異常:

System.NullReferenceException: Object reference not set to an instance of an object.

異常堆棧指向網關層控制器中的某一行代碼,通常是在調用微服務接口的位置。進一步分析發現,該異常是由于網關層控制器中依賴的服務接口實例為null導致的。

1.2 關鍵代碼場景

public class ProdcutController : AbpController, IProductService
{public IProductService ProductService { get; set; } // 屬性注入,實例為null[HttpGet]public async Task<PagedResultDto<ProductDto>> GetListAsync([FromQuery] PagedAndSortedResultRequestDto pagedAndSortedResultRequestDto){return await ProductService.GetListAsync(pagedAndSortedResultRequestDto); // 此處引發異常}
}

1.3 為什么注釋app.UseConfiguredEndpoints()可以解決問題

在ABP框架中,app.UseConfiguredEndpoints(); 方法用于注冊和啟用應用程序的路由系統,包括控制器路由的注冊和依賴注入容器的初始化。當注釋掉該方法后:

  1. 路由系統未啟用:網關層的控制器不會被注冊到路由系統中,請求不再由網關層的控制器處理
  2. Ocelot直接代理請求:請求被Ocelot直接捕獲并轉發到微服務,繞過了網關層的控制器
  3. 依賴注入問題被繞過:由于網關層控制器不再處理請求,依賴注入失敗導致的空引用異常不再觸發
// 原啟動配置
app.UseConfiguredEndpoints(); // 啟用路由系統,會觸發控制器依賴注入檢查
app.UseOcelot().Wait(); // 啟用Ocelot代理// 修改后配置(注釋掉UseConfiguredEndpoints)
// app.UseConfiguredEndpoints(); // 注釋掉,不啟用網關層路由系統
app.UseOcelot().Wait(); // Ocelot直接處理所有請求

1.4 本質原因與隱患

這種解決方案本質上是繞過了問題而非解決了問題,存在以下隱患:

  1. 網關層的自定義控制器功能失效
  2. 網關層的中間件和過濾器不再對請求生效
  3. 無法利用ABP框架的依賴注入和控制器特性

正確的解決方案應該是修復依賴注入配置,而不是繞過路由系統。

二、ABP微服務架構中HTTPS轉HTTP配置指南

2.1 為什么需要將HTTPS改為HTTP

在開發環境中,HTTPS配置可能會遇到以下問題:

  1. 證書配置復雜,需要信任開發證書
  2. 本地調試時HTTPS可能引發連接問題
  3. 微服務間通信使用HTTP更便捷

2.2 網關層Ocelot配置修改

2.2.1 修改Ocelot配置文件

找到網關層的ocelot.json配置文件,將所有DownstreamSchemehttps改為http,并調整端口:

{"Routes": [{"UpstreamPathTemplate": "/api/productservice/{everything}","DownstreamPathTemplate": "/api/productservice/{everything}","DownstreamScheme": "http", // 關鍵修改:從https改為http"DownstreamHostAndPorts": [{"Host": "localhost","Port": 50383 // 改為HTTP端口,與微服務的HTTP端口一致}],// 其他配置保持不變...}],"GlobalConfiguration": {"BaseUrl": "http://localhost:44376" // 改為http}
}
2.2.2 修改網關層啟動配置

在網關層的Program.csStartup.cs中,修改Kestrel配置為HTTP:

builder.WebHost.UseKestrel(options =>
{options.ListenAnyIP(44376, listenOptions =>{listenOptions.UseHttp(); // 關鍵修改:使用HTTP});
});

2.3 微服務層配置修改

2.3.1 修改微服務launchSettings.json

找到微服務的Properties/launchSettings.json,修改端口為HTTP:

{"iisSettings": {"iisExpress": {"applicationUrl": "http://localhost:50383", // 改為http"sslPort": 0 // 移除HTTPS端口配置}},"profiles": {"ProductService": {"commandName": "Project","launchBrowser": true,"applicationUrl": "http://localhost:50383", // 改為http"environmentVariables": {"ASPNETCORE_ENVIRONMENT": "Development"}}}
}
2.3.2 修改微服務Kestrel配置

在微服務的Program.cs中,修改Kestrel配置為HTTP:

builder.WebHost.UseKestrel(options =>
{options.ListenAnyIP(50383, listenOptions =>{listenOptions.UseHttp(); // 關鍵修改:使用HTTP});
});
2.3.3 修改微服務appsettings.json

將微服務的appsettings.json中的SelfUrl改為HTTP:

{"App": {"SelfUrl": "http://localhost:50383", // 改為http"ClientUrl": "http://localhost:4200","CorsOrigins": "http://*.ProductService.com,http://localhost:4200"},// 其他配置保持不變...
}

2.4 認證與授權配置調整

如果使用了認證授權服務,需要修改相關配置為HTTP:

// 網關層appsettings.json
{"AuthServer": {"Authority": "http://localhost:50399", // 改為http和認證服務的HTTP端口"RequireHttpsMetadata": false,"SwaggerClientId": "WebSite_Gateway_Swagger"},// 其他配置保持不變...
}

2.5 驗證HTTP配置

  1. 啟動微服務,確認控制臺輸出為HTTP端口:
Now listening on: http://localhost:50383
Application started.
  1. 使用Postman測試微服務接口:
http://localhost:50383/api/productservice/product
  1. 測試網關轉發:
http://localhost:44376/api/productservice/product

三、網關層依賴注入問題的正確解決方案

雖然注釋app.UseConfiguredEndpoints();可以暫時解決空引用異常,但這不是正確的解決方案。正確的做法是修復依賴注入配置:

3.1 使用構造函數注入

public class ProductController : AbpController
{private readonly IProductService _productService;// 構造函數注入確保服務實例被正確初始化public ProductController(IProductService productService){_productService = productService;}[HttpGet]public async Task<PagedResultDto<ProductDto>> GetListAsync([FromQuery] PagedAndSortedResultRequestDto pagedAndSortedResultRequestDto){return await _productService.GetListAsync(pagedAndSortedResultRequestDto);}
}

3.2 注冊服務到依賴注入容器

在網關層模塊中注冊遠程服務代理:

public override void ConfigureServices(ServiceConfigurationContext context)
{// 注冊遠程服務代理context.Services.AddProxy<ProductService.Contracts.IProductService>(remoteServiceName: "ProductService",proxyUrl: "http://localhost:50383");
}

3.3 啟用路由系統

恢復app.UseConfiguredEndpoints();并確保其在Ocelot之前調用:

app.UseRouting();
app.UseConfiguredEndpoints(); // 啟用路由系統
app.UseOcelot().Wait(); // 啟用Ocelot代理

四、總結與最佳實踐

4.1 問題解決思路總結

  1. System.NullReferenceException在網關層通常是由于依賴注入失敗導致的,注釋app.UseConfiguredEndpoints();只是繞過了問題,而非解決問題
  2. 將HTTPS改為HTTP可以簡化開發環境的配置,但生產環境應使用HTTPS保證安全
  3. 正確的解決方案是修復依賴注入配置,使用構造函數注入并正確注冊服務

4.2 開發環境最佳實踐

  1. 依賴注入:始終使用構造函數注入,避免屬性注入
  2. 路由配置:正確配置網關層和微服務的路由,確保請求正確轉發
  3. HTTPS/HTTP:開發環境可使用HTTP簡化配置,生產環境必須使用HTTPS
  4. 日志記錄:啟用詳細日志,便于問題排查
  5. 異常處理:添加全局異常處理,避免應用崩潰

僅供參考

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/87637.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/87637.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/87637.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

啊啊啊啊啊啊啊啊code

前序遍歷和中序遍歷構建二叉樹 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNod…

【算法 day06】LeetCode 454.四數相加II | 15. 三數之和 | 18. 四數之和

454.四數相加II 題目鏈接 | 文檔講解 |視頻講解 : 鏈接 1.思路&#xff1a; 0.定義一個count&#xff0c;計算最終出現的次數 1.先遍歷nums1和nums2,求出兩者的和&#xff0c;map的key是和&#xff0c;value是出現的次數 2.再遍歷nums3和nums4&#xff0c;求出0-兩者的和 3…

【項目實訓】【項目博客#09】HarmonySmartCodingSystem系統后端智能API檢索與代碼助手實現(6.2-6.15)

【項目實訓】【項目博客#09】HarmonySmartCodingSystem系統后端智能API檢索與代碼助手實現&#xff08;6.2-6.15&#xff09; 文章目錄 【項目實訓】【項目博客#09】HarmonySmartCodingSystem系統后端智能API檢索與代碼助手實現&#xff08;6.2-6.15&#xff09;項目博客概述一…

【JVM】- 類加載與字節碼結構3

類加載階段 1. 加載 加載&#xff1a;將類的字節碼載入方法區中&#xff0c;內部采用C的instanceKlass描述java類。如果這個類的父類還沒加載&#xff0c;則先加載父類加載和鏈接可能是交替運行的 通過全限定名獲取字節碼 從文件系統&#xff08;.class 文件&#xff09;、JA…

Qt藍圖式技能編輯器狀態機模塊設計與實現

設計概述 這個模塊是一個基于Qt的藍圖式技能編輯器狀態機&#xff0c;主要用于游戲開發中的技能狀態管理。核心功能包括&#xff1a; 狀態節點&#xff08;開始、結束、普通狀態&#xff09;的可視化 狀態間連線的繪制與管理 狀態轉換邏輯的可視化編輯 動作選擇與配置 核…

Unity AR識別物體的內容語音讀取+使用說明功能

因之前一直在開發項目&#xff0c;斷斷續續寫了一點博客&#xff0c;最后統一寫了一下博客記錄學習內容。 可以看到我的工作一直在進行。 目錄 一、識別內容語音讀取 二、點擊齒輪按鈕彈出使用說明界面 開發步驟 1. 創建齒輪按鈕 UI 2. 創建使用說明面板 UI 3. 編寫控制…

Unable to start embedded Tomcat

通常是由于xml文件配置錯誤導致 1. mapper 指向錯誤 <resultMap id"Waybill" type"c.Waybill"> 2. 字段類型錯誤 <result column"wstatus" property"stus" javaType"TINYINT"/>TINYINT 是數據庫類型<resu…

Mac電腦 充電限制保護工具 AlDente Pro

AlDente Pro一款充電限制保護工具&#xff0c;是可以限制最大充電百分比來保護電池的工具。 鋰離子和聚合物電池&#xff08;如 MacBook 中的電池&#xff09;在40&#xff05; 至 80&#xff05; 之間運行時&#xff0c;使用壽命最長。 始終將電池電量保持在 100&#xff05…

KungfuBot——基于物理約束和自適應運動追蹤的人形全身控制PBHC,用于學習打拳或跳舞(即RL下的動作模仿和運控)

前言 昨天618&#xff0c;我司「七月在線」同事朝陽為主力&#xff0c;我打雜&#xff0c;折騰了整整一天&#xff0c;終于可以通過VR搖操宇樹G1了——當然&#xff0c;搖操是為了做訓練數據的采集&#xff0c;從而方便 下一步的模型(策略)訓練&#xff0c;最終實現機器人自主…

Kafka多副本機制

副本和副本因子 Kafka 會為每個 Partition 創建多個副本。這些副本分布在不同的 Broker 上。副本確保了數據的冗余存儲&#xff0c;即使某個 Broker 宕機或失效&#xff0c;其他副本可以繼續提供服務。 副本因子指的是每個 Partition 有多少個副本。副本因子的設置決定了一個…

Vue3類似百度風格搜索框組件

Vue3百度風格搜索框組件&#xff0c;使用vue3進行設計&#xff0c;亦有vue3TS的版本。 vue3組件如下&#xff1a; <template><!-- 搜索組件容器 --><div class"search-container"><!-- 百度Logo - 新樣式 --><div class"logo-conta…

智凈未來:華為智選IAM以科技巧思優化家庭健康飲水體驗

在中國家庭中&#xff0c;凈水器早已成為廚房標配&#xff0c;但傳統凈水設備的使用體驗卻遠未達到理想狀態。根據《2023年中國家庭凈水器使用調研報告》顯示&#xff0c;超過65%的用戶對傳統凈水器存在不滿&#xff0c;主要痛點集中在功能單一、操作復雜、維護麻煩、噪音大、廢…

細說STM32單片機SPI-Flash芯片的FatFS移植

目錄 一、SPI-Flash芯片硬件電路 二、CubeMX項目基礎設置 1、RCC、SYS、Code Generator、USART6、NVIC 2、RTC 3、SPI2 4、GPIO 5、FatFS模式 6、FatFS參數設置概述 &#xff08;1&#xff09;Version組 &#xff08;2&#xff09;Function Parameters組 1&#x…

ubuntu 22.04 安裝部署logstash 7.10.0詳細教程

安裝部署logstash 7.10.0詳細教程 一、下載并安裝二、新建配置文件三、賦權文件權限四、檢測文件grok語法是否異常五、啟動服務六、安裝啟動常見問題 【背景】 整個elk安裝是基于ubuntu 22.04和jdk 11環境。logstash采用 *.deb方式安裝&#xff0c;需要服務器能聯網。ubuntu 22…

JVM對象創建與內存分配機制深度剖析

對象創建的主要流程 類加載檢查 在創建對象之前&#xff0c;JVM 首先會檢查該類是否已經加載、解析并初始化&#xff1a; 如果沒有&#xff0c;則會通過類加載機制加載類元信息&#xff08;Class Metadata&#xff09;到方法區。 這個過程包括&#xff1a;加載&#xff08;load…

Navicat 技術指引 | TiDB 的 AI 查詢交互功能

目前&#xff0c;Navicat 兩款工具支持對 TiDB 數據庫的管理開發功能&#xff1a;一款是旗艦款 Navicat Premium&#xff0c;另一款是其輕量化功能的 Navicat Premium Lite&#xff08;官方輕量級免費版&#xff09;。Navicat 自版本 17.1 開始支持 TiDB 7。它支持的系統有 Win…

以list為輸入條件,查詢數據庫表,java中的mapper層和mybatis層應該怎么寫?

根據一個 List 中的兩個字段 rangeCode 和 unitcd&#xff0c;查詢數據庫表 model_engineering_spatial_unit。這個需求在 Java MyBatis 項目中非常常見&#xff0c;下面我將為你詳細寫出 Mapper 接口&#xff08;Java&#xff09; 和 MyBatis XML 映射文件 的寫法。 ? 前提…

pyspark 創建DataFrame

from pyspark.sql import SparkSession from pyspark.sql import StructType, StructField, IntegerType,StringType spark SparkSession.builder.appName(test).getOrCreate() 1、 從列表中創建DataFrame data [(1,"alice"),(2,Blob),(3,Charlie)] columns [&qu…

Vim:從入門到進階的高效文本編輯器之旅

目錄 一、Vim簡介 二、Vim的基礎操作 2.1 進入和退出Vim 2.2 Vim的三種模式 2.3 基礎移動 三、Vim的高效編輯技巧 3.1 文本編輯 3.2 文本刪除與修改 3.3 復制與粘貼 四、Vim的進階使用 4.1 搜索與替換 4.2 寄存器與宏 4.3 插件與配置 五、結語 在編程界&#xff0…

Docker基礎理論與阿里云Linux服務器安裝指南

文章目錄 一、Docker核心概念二、阿里云環境準備三、Docker安裝與配置四、核心容器部署示例五、開發環境容器化六、運維管理技巧七、安全加固措施 一、Docker核心概念 容器化本質&#xff1a; 輕量級虛擬化技術&#xff0c;共享主機內核進程級隔離&#xff08;cgroups/namespac…