在 GCP 中部署后获取空指针异常
Getting null pointer exception after deployment in GCP
我有一个分为微服务的 .NET 应用程序。微服务之一是编排器和身份验证器:该微服务与其他 3 个微服务通信,并且相互通信是通过 REST 完成的。
实现的代码在本地完全可用,每个微服务也用 docker 进行了容器化并在本地进行了测试(也没有错误)。
当我们尝试在 GCP 中测试我们的服务时,问题就出现了:错误总是一样的,都是空指针异常,如下图所示:
我们在代码中定义了与用于进行部署的 .yml
文件匹配的环境变量。
这是我们正在使用的.yml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: orchauth
namespace: default
labels:
app: orchauth
spec:
strategy:
type: Recreate
replicas: 2
selector:
matchLabels:
app: orchauth
template:
metadata:
labels:
app: orchauth
spec:
serviceAccountName: default
containers:
- name: orchauth
image: "eu.gcr.io/boomoseries-api/orchmicroservice"
ports:
- containerPort: 80
env:
- name: SEARCH_HOST
value: "http://search.default"
- name: USERS_HOST
value: "http://users.default"
- name: PREFS_HOST
value: "http://prefs.default"
---
apiVersion: v1
kind: Service
metadata:
name: orchauth
spec:
selector:
app: orchauth
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
文件中其他微服务的实现方式类似。
我们还在代码中定义了微服务环境变量,正确:
private static readonly string microservicesBaseURL = Environment.GetEnvironmentVariable("SEARCH_HOST");
private static readonly string microservicesBaseURL = Environment.GetEnvironmentVariable("USERS_HOST");
private static readonly string microservicesBaseURL = Environment.GetEnvironmentVariable("PREFS_HOST");
这是入口 .yml
文件:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: boomoseries-ingress
spec:
ingressClassName: nginx
defaultBackend:
service:
name: orchauth
port:
number: 80
入口与微服务 OrchAuth 通信,这是给出错误的那个。
请求出现错误:根据我的理解,request
变量为null,这里出现空指针异常。但我不明白为什么,因为在本地和 containarized 服务工作没有问题。代码如下(classSearchRESTComunicationServiceBooks
):
public async Task<List<BookDTO>> ObtainBooksByRating(string type, double minRating)
{
List<BookDTO> booksDtos = new();
//Makes the requests to different microservices
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var request = httpClient.GetAsync(microservicesBaseURL + "?type=" + type + "&minRating=" + minRating);
stopwatch.Stop();
System.Diagnostics.Debug.WriteLine(stopwatch.ElapsedMilliseconds);
//Get the responses
var response = request.Result;
var responseString = await response.Content.ReadAsStringAsync();
List<BookDTO> deserializedBook = JsonConvert.DeserializeObject<List<BookDTO>>(responseString);
foreach (var item in deserializedBook)
{
booksDtos.Add(item);
}
return booksDtos;
注意:我完全知道代码有不好的实现实践,但这不是主要问题。感谢您花时间阅读。
所以问题出在我的 .yml 文件中,我只是将我的服务配置为使用端口 80 (http)。在我的初创公司中,我使用的是 Hsts,这意味着总是会重定向到 https 端口(配置为 443)。将这个端口添加到.yml文件后,问题解决
我有一个分为微服务的 .NET 应用程序。微服务之一是编排器和身份验证器:该微服务与其他 3 个微服务通信,并且相互通信是通过 REST 完成的。
实现的代码在本地完全可用,每个微服务也用 docker 进行了容器化并在本地进行了测试(也没有错误)。
当我们尝试在 GCP 中测试我们的服务时,问题就出现了:错误总是一样的,都是空指针异常,如下图所示:
.yml
文件匹配的环境变量。
这是我们正在使用的.yml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: orchauth
namespace: default
labels:
app: orchauth
spec:
strategy:
type: Recreate
replicas: 2
selector:
matchLabels:
app: orchauth
template:
metadata:
labels:
app: orchauth
spec:
serviceAccountName: default
containers:
- name: orchauth
image: "eu.gcr.io/boomoseries-api/orchmicroservice"
ports:
- containerPort: 80
env:
- name: SEARCH_HOST
value: "http://search.default"
- name: USERS_HOST
value: "http://users.default"
- name: PREFS_HOST
value: "http://prefs.default"
---
apiVersion: v1
kind: Service
metadata:
name: orchauth
spec:
selector:
app: orchauth
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
文件中其他微服务的实现方式类似。 我们还在代码中定义了微服务环境变量,正确:
private static readonly string microservicesBaseURL = Environment.GetEnvironmentVariable("SEARCH_HOST");
private static readonly string microservicesBaseURL = Environment.GetEnvironmentVariable("USERS_HOST");
private static readonly string microservicesBaseURL = Environment.GetEnvironmentVariable("PREFS_HOST");
这是入口 .yml
文件:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: boomoseries-ingress
spec:
ingressClassName: nginx
defaultBackend:
service:
name: orchauth
port:
number: 80
入口与微服务 OrchAuth 通信,这是给出错误的那个。
请求出现错误:根据我的理解,request
变量为null,这里出现空指针异常。但我不明白为什么,因为在本地和 containarized 服务工作没有问题。代码如下(classSearchRESTComunicationServiceBooks
):
public async Task<List<BookDTO>> ObtainBooksByRating(string type, double minRating)
{
List<BookDTO> booksDtos = new();
//Makes the requests to different microservices
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var request = httpClient.GetAsync(microservicesBaseURL + "?type=" + type + "&minRating=" + minRating);
stopwatch.Stop();
System.Diagnostics.Debug.WriteLine(stopwatch.ElapsedMilliseconds);
//Get the responses
var response = request.Result;
var responseString = await response.Content.ReadAsStringAsync();
List<BookDTO> deserializedBook = JsonConvert.DeserializeObject<List<BookDTO>>(responseString);
foreach (var item in deserializedBook)
{
booksDtos.Add(item);
}
return booksDtos;
注意:我完全知道代码有不好的实现实践,但这不是主要问题。感谢您花时间阅读。
所以问题出在我的 .yml 文件中,我只是将我的服务配置为使用端口 80 (http)。在我的初创公司中,我使用的是 Hsts,这意味着总是会重定向到 https 端口(配置为 443)。将这个端口添加到.yml文件后,问题解决