在整合.Net的過程中遇到不少問題,一般網上的例子只是調用一個簡單的NodeJS示例,並未有詳細的介紹及采坑過程。
首先,我的項目結構是:Vue前端 + SpringCloud后端 + .Net的WebApi后端
項目改造目標:Vue前端訪問后端的網關Zuul,由Zuul配置請求轉發,給SpringCloud微服務或者.Net的服務上。
要准備的SpringCloud工程有三個:Eureka服務端、Zuul網關服務、Sidecar的異構系統服務
1、Eureka就不多廢話了
2、Zuul為了調試方便,加上Cors跨域訪問的配置:
@Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowCredentials(true); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedMethod("*"); source.registerCorsConfiguration("/**", corsConfiguration); return new CorsFilter(source); } }
- 此處有一個跨域訪問的坑:
瀏覽器會返回200但是得不到數據,並拋出異常: The 'Access-Control-Allow-Origin' header contains multiple values but only one
意思就是不能處理多個跨域的返回值,首先Zuul的跨域不能關閉,否則不能通過瀏覽器正常訪問,那么到.Net的代碼里關閉跨域配置:
//config.EnableCors(new EnableCorsAttribute(WebSettingsConfig.CorsIp, "*", "*") { SupportsCredentials = true });
Zuul的application.yml
zuul:
ignoredServices: '*'
routes:
oldsys:
path: /api/**
serviceId: oldsys
strip-prefix: false
- 此處一個請求轉發的坑:
zuul轉發給內部服務的時候會把Url的前綴剪掉,到達.net服務的Url變成了 http://localhost:17793/xxx
可以通過設置 strip-prefix: false 把Url還原成 http://localhost:17793/api/xxx 這樣保留原來請求的完整請求路徑。
順便提一下原理,在SimpleRouteLocator.java類中,有這樣一個方法就是此配置生效的原因:
if (route.isStripPrefix()) { //這里有個判斷 int index = route.getPath().indexOf("*") - 1; if (index > 0) { String routePrefix = route.getPath().substring(0, index); targetPath = targetPath.replaceFirst(routePrefix, ""); prefix = prefix + routePrefix; } }
3、sidecar服務
啟動程序,開啟sidecar:
@SpringBootApplication @EnableSidecar public class CapaOldSysApp { public static void main(String[] args) { SpringApplication.run(CapaOldSysApp.class, args); } }
Sidecar的application.yml
sidecar:
ip-address: localhost
port: 17793
health-uri: http://localhost:17793/health.json
- 此處有很多坑,大多數是 Bad Request - Invalid Hostname HTTP Error 400. The request hostname is invalid. 錯誤:
- 如果不設置sidecar異構系統的ip地址,也就是ip-address項,有可能讀取不同網卡上(比如:虛擬機)的地址,導致請求發送不到目標系統上。
- 為目標系統創建health.json靜態文件,並保證health-uri指定的地址可以被訪問到,Eureka上狀態為DOWN的服務是訪問不了的。IIS服務器需要開啟MiME設置。
- 查看http://localhost:8080/hosts/oldsys 的信息,確定host及port是不是目標系統的正確地址。
{
host: "localhost",
port: 17793,
metadata: {},
uri: "http://localhost:17793",
serviceId: "OLDSYS",
secure: false,
instanceInfo: {
instanceId: "192.168.161.1:8080",
app: "OLDSYS",
appGroupName: null,
ipAddr: "localhost",
sid: "na",
homePageUrl: "http://localhost:17793/",
statusPageUrl: "http://localhost:8080/info",
healthCheckUrl: "http://localhost:8080/health",
secureHealthCheckUrl: null,
vipAddress: "oldsys",
secureVipAddress: "oldsys",
countryId: 1,
dataCenterInfo: {
@class: "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
name: "MyOwn"
},
hostName: "localhost",
status: "UP",
leaseInfo: {
renewalIntervalInSecs: 30,
durationInSecs: 90,
registrationTimestamp: 1557805465685,
lastRenewalTimestamp: 1557805733435,
evictionTimestamp: 0,
serviceUpTimestamp: 1557805343392
},
isCoordinatingDiscoveryServer: false,
metadata: {},
lastUpdatedTimestamp: 1557805465686,
lastDirtyTimestamp: 1557805465682,
actionType: "ADDED",
asgName: null,
overriddenStatus: "UNKNOWN"
}
}
IIS需要增加地址綁定,才可以用localhost以外的地址訪問,更改.net程序的applicationhost.conf(調試環境在任務欄中找到IIS Express)可以增加地址映射:
<bindings>
<binding protocol="http" bindingInformation="*:17793:localhost" />
<binding protocol="http" bindingInformation="*:17793:127.0.0.1" />
</bindings>
其他的就沒有什么可以注意的了,Eureka應用列表服務狀態不能為DOWN,有時候Zuul需要同步Eureka的數據,首次訪問基本不成功,多刷新幾次。