-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PROTOTYPE] Combine gRPC and HTTP servers #3765
Conversation
We have just merged an amendment to the spec that says gRPC and HTTP servers use different ports: open-telemetry/opentelemetry-specification#1839 because the previous research concluded it is not possible. Is there now a new evidence that it is possible? Not sure what we do with spec change if that's the case. If we absolutely certain this is doable we may need to revert the spec change.
There is a proposal that enables this via a new concept called PDataContext: #3745 |
@a-feld would you be able to make progress on this in the next couple days? I have reverted the recent spec change that has split the ports. The spec is now waiting for the final decision that we make here. If we are able to serve OTLP/gRPC and OTLP/HTTP on one port we will keep the spec as is, if not we will do the splitting as it was planned. |
@tigrannajaryan will do! I'm splitting my time between this PR and open-telemetry/opentelemetry-collector-contrib#4444 I'll try to make some progress on this PR today! |
I didn't get to this today. I'm actually out on holiday next week but I'll try to make progress on Monday so that we can push this forward. |
The majority of the logic changes simply extract the http2.Server into the ToServer method so that it is accessible for adding the h2c handler.
By default, the experimental server is disabled. If enabled, the default endpoint is set to 0.0.0.0:4317.
61fb0bb
to
1b0a9e0
Compare
@tigrannajaryan I made some progress on this PR today. I focused on simplifying the diff and breaking out the commits so that it's more easily reviewable. Using @bogdandrutu 's suggestion from the SIG last week, I created a new The only truly different change here is that there is an Please let me know what your thoughts are! If acceptable, I'll continue to build out robust testing of this new change. |
@open-telemetry/collector-approvers @Aneurysm9 @dashpole @jmacd or anyone else who have experience with Golang HTTP server and gRPC, can you help review this? This is a relatively small but important and high impact change and it would be great to have several eyes on this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a unit test that verifies that experimental mode with actual OTLP receiver and OTLP/gRPC and OTLP/HTTP exporers.
|
||
// Declare an HTTP/2 server which will handle any H2 protocol traffic | ||
h2Server := &http2.Server{ | ||
NewWriteScheduler: func() http2.WriteScheduler { return http2.NewPriorityWriteScheduler(nil) }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment to explain why we need priority scheduler and not the default one.
@@ -202,6 +203,11 @@ func (r *otlpReceiver) registerTraceConsumer(tc consumer.Traces) error { | |||
return componenterror.ErrNilNextConsumer | |||
} | |||
r.traceReceiver = trace.New(r.cfg.ID(), tc) | |||
if r.cfg.ExperimentalServerEnabled { | |||
r.httpMux.HandleFunc("/opentelemetry.proto.collector.trace.v1.TraceService/Export", func(resp http.ResponseWriter, req *http.Request) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit fragile. If we rename a message or service in the proto this will no longer work. Can we have a test that ensures the path for this handler matches the proto definition correctly?
Or maybe event better, there is a way to get this string from generated protobuf *.pb.go files? (I don't see it).
if r.cfg.ExperimentalServerEnabled { | ||
r.httpMux.HandleFunc("/opentelemetry.proto.collector.metrics.v1.MetricsService/Export", func(resp http.ResponseWriter, req *http.Request) { | ||
handleMetrics(resp, req, grpcContentType, r.metricsReceiver, metricsPbUnmarshaler) | ||
}).Methods(http.MethodPost).Headers("Content-Type", grpcContentType) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be inside if r.httpMux != nil {
check? Not sure when can r.httpMux
be nil though. Perhaps it can't anymore since we always create http server when ExperimentalServerEnabled?
var err error | ||
resp, err = newGrpcResponseWriter(resp, req) | ||
if err != nil { | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Should we read and close the body even if this errors out? Just wondering if otherwise it may leak memory since the request is pending somewhere.
- Should we return an InternalServerError to the client especially since we don't record the error in any other way here?
@@ -57,7 +96,7 @@ func handleTraces( | |||
} | |||
|
|||
// TODO: Pass response from grpc handler when otlpgrpc returns concrete type. | |||
writeResponse(resp, contentType, http.StatusOK, &types.Empty{}) | |||
writeResponse(resp, contentType, http.StatusOK, emptyMessage) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was a bit confused by this. For clarity we should probably write proper Export*ServiceResponse
protobuf message, which indeed is empty right now, but may not be empty in the future if the proto evolves.
grpcRw.WriteHeader(int(codes.Internal)) | ||
compressed, err := unwrapProtoFromGrpc(req.Body) | ||
if err != nil { | ||
writeError(grpcRw, grpcContentType, err, http.StatusBadRequest) | ||
return nil, err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add some comments to explain what happens here and why.
if s, ok := rsp.(*spb.Status); ok { | ||
statusCode = int(s.Code) | ||
w.Header().Set(grpcMessage, s.Message) | ||
rsp = emptyMessage | ||
} else { | ||
statusCode = int(codes.OK) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any links to gRPC specs that make it clear that this is the right thing to do? Similarly for other code that deals with gRPC peculiarities.
During last week's SIG Collector call, we discussed this and agreed to make this opt-in for at least a couple of releases, to get people to test it in the real world. My biggest concern right now is that we do not know how it would impact load balancers and proxies that are aware of gRPC, like NGINX and some service meshes. If we can get this change as a forked OTLP receiver in the contrib, we can then compare the two implementations. With that data, we'll be able to make a better decision. |
Thanks for the feedback @tigrannajaryan and @jpkrohling !
@jpkrohling The change as currently defined is definitely opt-in. The usage of this new feature requires |
@jpkrohling are you specifically looking for a fork? It seems to be an option would be sufficient and will allow us to test the new behavior while keeping the old behavior intact. Please clarify what you had in your mind with forking. We do definitely need tests that verify the new behavior anyway, including end-to-end using our own OTLP/gRPC and OTLP/HTTP exporters. |
I mean to have another OTLP receiver in the contrib repository using this new approach. |
I understand. I wonder if we get about the same level of testability with the opt-in If we are going to fork then to be completely safe forking will require to also fork |
I guess it depends on how intrusive the changes are. I remember asking @a-feld about it, and he mentioned that they were pretty intrusive. |
I would like to know as well, but since I am not familiar with Go's http server implementation and gRPC in general it is hard for me to assess the impact. It would be great if someone who is deeply familiar with it to chime in. |
This PR was marked stale due to lack of activity. It will be closed in 7 days. |
@a-feld do you plan to continue working on this? |
Hi @tigrannajaryan I've been waiting for #3890 to get merged. Also, as a bit of news - I have resigned from New Relic effective 9/24/2021 so I will be closing any open PRs after that date. I'm happy to continue to work to get these PRs merged in until then! After that time, I will be unable to submit further contributions until further notice. |
This PR was marked stale due to lack of activity. It will be closed in 7 days. |
Driveby reminder that @a-feld will close this PR in two days. Is merging ports still the canonical plan? Is there someone else who can take on the work using the same code, on the basis that it's been contributed by New Relic to CNCF, or does the next person need to start blank? |
@bogdandrutu to review and merger prior to 9/24 |
This will not likely be merged by 9/24. I'll go ahead and close this out for others to pick up. |
Related to open-telemetry#1816 Fixes open-telemetry#1835 Fixes open-telemetry#1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: open-telemetry/opentelemetry-collector#1256 The conclusion is that there are technical hurdles that make it unfeasible: open-telemetry/opentelemetry-collector#1256 (comment) Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: open-telemetry#1148 (comment) There was also a draft PR to merge the ports in the Collector but it was not completed: open-telemetry/opentelemetry-collector#3765 Note that this change was initially submitted in PR open-telemetry#1839 and then reverted in PR open-telemetry#1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on.
Related to open-telemetry#1816 Fixes open-telemetry#1835 Fixes open-telemetry#1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: open-telemetry/opentelemetry-collector#1256 The conclusion is that there are technical hurdles that make it unfeasible: open-telemetry/opentelemetry-collector#1256 (comment) Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: open-telemetry#1148 (comment) There was also a draft PR to merge the ports in the Collector but it was not completed: open-telemetry/opentelemetry-collector#3765 Note that this change was initially submitted in PR open-telemetry#1839 and then reverted in PR open-telemetry#1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on.
Related to #1816 Fixes #1835 Fixes #1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: open-telemetry/opentelemetry-collector#1256 The conclusion is that there are technical hurdles that make it unfeasible: open-telemetry/opentelemetry-collector#1256 (comment) Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: #1148 (comment) There was also a draft PR to merge the ports in the Collector but it was not completed: open-telemetry/opentelemetry-collector#3765 Note that this change was initially submitted in PR #1839 and then reverted in PR #1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on. Note 2: we consider this a spec bug fix (spec was impossible to implement), rather than a functionality change, that's why we believe this is an allowed change.
Related to open-telemetry/opentelemetry-specification#1816 Fixes open-telemetry/opentelemetry-specification#1835 Fixes open-telemetry/opentelemetry-specification#1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: open-telemetry/opentelemetry-collector#1256 The conclusion is that there are technical hurdles that make it unfeasible: open-telemetry/opentelemetry-collector#1256 (comment) Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: open-telemetry/opentelemetry-specification#1148 (comment) There was also a draft PR to merge the ports in the Collector but it was not completed: open-telemetry/opentelemetry-collector#3765 Note that this change was initially submitted in PR open-telemetry/opentelemetry-specification#1839 and then reverted in PR open-telemetry/opentelemetry-specification#1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on. Note 2: we consider this a spec bug fix (spec was impossible to implement), rather than a functionality change, that's why we believe this is an allowed change.
Related to open-telemetry/opentelemetry-specification#1816 Fixes open-telemetry/opentelemetry-specification#1835 Fixes open-telemetry/opentelemetry-specification#1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: open-telemetry/opentelemetry-collector#1256 The conclusion is that there are technical hurdles that make it unfeasible: open-telemetry/opentelemetry-collector#1256 (comment) Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: open-telemetry/opentelemetry-specification#1148 (comment) There was also a draft PR to merge the ports in the Collector but it was not completed: open-telemetry/opentelemetry-collector#3765 Note that this change was initially submitted in PR open-telemetry/opentelemetry-specification#1839 and then reverted in PR open-telemetry/opentelemetry-specification#1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on. Note 2: we consider this a spec bug fix (spec was impossible to implement), rather than a functionality change, that's why we believe this is an allowed change.
Related to open-telemetry/opentelemetry-specification#1816 Fixes open-telemetry/opentelemetry-specification#1835 Fixes open-telemetry/opentelemetry-specification#1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: open-telemetry/opentelemetry-collector#1256 The conclusion is that there are technical hurdles that make it unfeasible: open-telemetry/opentelemetry-collector#1256 (comment) Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: open-telemetry/opentelemetry-specification#1148 (comment) There was also a draft PR to merge the ports in the Collector but it was not completed: open-telemetry/opentelemetry-collector#3765 Note that this change was initially submitted in PR open-telemetry/opentelemetry-specification#1839 and then reverted in PR open-telemetry/opentelemetry-specification#1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on. Note 2: we consider this a spec bug fix (spec was impossible to implement), rather than a functionality change, that's why we believe this is an allowed change.
Related to open-telemetry/opentelemetry-specification#1816 Fixes open-telemetry/opentelemetry-specification#1835 Fixes open-telemetry/opentelemetry-specification#1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: open-telemetry/opentelemetry-collector#1256 The conclusion is that there are technical hurdles that make it unfeasible: open-telemetry/opentelemetry-collector#1256 (comment) Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: open-telemetry/opentelemetry-specification#1148 (comment) There was also a draft PR to merge the ports in the Collector but it was not completed: open-telemetry/opentelemetry-collector#3765 Note that this change was initially submitted in PR open-telemetry/opentelemetry-specification#1839 and then reverted in PR open-telemetry/opentelemetry-specification#1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on. Note 2: we consider this a spec bug fix (spec was impossible to implement), rather than a functionality change, that's why we believe this is an allowed change.
Related to open-telemetry/opentelemetry-specification#1816 Fixes open-telemetry/opentelemetry-specification#1835 Fixes open-telemetry/opentelemetry-specification#1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: open-telemetry/opentelemetry-collector#1256 The conclusion is that there are technical hurdles that make it unfeasible: open-telemetry/opentelemetry-collector#1256 (comment) Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: open-telemetry/opentelemetry-specification#1148 (comment) There was also a draft PR to merge the ports in the Collector but it was not completed: open-telemetry/opentelemetry-collector#3765 Note that this change was initially submitted in PR open-telemetry/opentelemetry-specification#1839 and then reverted in PR open-telemetry/opentelemetry-specification#1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on. Note 2: we consider this a spec bug fix (spec was impossible to implement), rather than a functionality change, that's why we believe this is an allowed change.
Related to open-telemetry/opentelemetry-specification#1816 Fixes open-telemetry/opentelemetry-specification#1835 Fixes open-telemetry/opentelemetry-specification#1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: open-telemetry/opentelemetry-collector#1256 The conclusion is that there are technical hurdles that make it unfeasible: open-telemetry/opentelemetry-collector#1256 (comment) Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: open-telemetry/opentelemetry-specification#1148 (comment) There was also a draft PR to merge the ports in the Collector but it was not completed: open-telemetry/opentelemetry-collector#3765 Note that this change was initially submitted in PR open-telemetry/opentelemetry-specification#1839 and then reverted in PR open-telemetry/opentelemetry-specification#1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on. Note 2: we consider this a spec bug fix (spec was impossible to implement), rather than a functionality change, that's why we believe this is an allowed change.
Related to open-telemetry/opentelemetry-specification#1816 Fixes open-telemetry/opentelemetry-specification#1835 Fixes open-telemetry/opentelemetry-specification#1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: open-telemetry/opentelemetry-collector#1256 The conclusion is that there are technical hurdles that make it unfeasible: open-telemetry/opentelemetry-collector#1256 (comment) Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: open-telemetry/opentelemetry-specification#1148 (comment) There was also a draft PR to merge the ports in the Collector but it was not completed: open-telemetry/opentelemetry-collector#3765 Note that this change was initially submitted in PR open-telemetry/opentelemetry-specification#1839 and then reverted in PR open-telemetry/opentelemetry-specification#1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on. Note 2: we consider this a spec bug fix (spec was impossible to implement), rather than a functionality change, that's why we believe this is an allowed change.
Related to open-telemetry/opentelemetry-specification#1816 Fixes open-telemetry/opentelemetry-specification#1835 Fixes open-telemetry/opentelemetry-specification#1920 Some historical context: we wanted to make grpc and http use the same port and we had an open issue in the Collector to do so: open-telemetry/opentelemetry-collector#1256 The conclusion is that there are technical hurdles that make it unfeasible: open-telemetry/opentelemetry-collector#1256 (comment) Because of that we need to keep grpc and http ports separate. This means we need to change the spec to say that otlp/http uses port 4318. Once this PR is merged we will also need to submit for port 4318 registration with IANA like we did previously with port 4317: open-telemetry/opentelemetry-specification#1148 (comment) There was also a draft PR to merge the ports in the Collector but it was not completed: open-telemetry/opentelemetry-collector#3765 Note that this change was initially submitted in PR open-telemetry/opentelemetry-specification#1839 and then reverted in PR open-telemetry/opentelemetry-specification#1847 because we hoped that the merging could be successfully done. We believe that we should no longer pursue this and should consider the ports separate from now on. Note 2: we consider this a spec bug fix (spec was impossible to implement), rather than a functionality change, that's why we believe this is an allowed change.
gRPC / HTTP server consolidation 🚧 [PROTOTYPE] 🚧
This PR consolidates the gRPC server and HTTP servers into 1 centralized server. The architecture of this solution enables:
Notes