Автор оригинала: David Wong.
Если вы когда-либо занимались gRPC + gRPC Шлюз раньше вы обязательно сталкивались с этой проблемой. “Почему мы должны включать TLS для достижения двойного трафика на одном и том же порту, можем ли мы не включать его?” Или “Я не хочу использовать сертификаты для реализации этих функций, хорошо?” 。 Бесчисленное множество людей много раз спрашивали меня об этих проблемах и убедили многих людей, но убеждение не означает сдаваться. Не в позапрошлом году, не значит не в этом году, сегодня я надеюсь поделиться контекстом и конкретными способами достижения для вас.
Адрес: Шлюз gRPC + gRPC не может использовать сертификаты?
Прошлые времена
Почему H2 не работает
потому что net/http2 Поддерживается только идентификатор “h2”, в то время как идентификатор “h2” HTTP/2 должен использовать протокол безопасности транспортного уровня (TLS), который используется для полей согласования протокола прикладного уровня TLS и идентификации HTTP/2 по протоколу TLS.
Проще говоря, вот и все. сеть/http2 Для взаимодействия необходимо использовать протокол TLS. Вообще говоря, требуются сертификаты, поэтому, конечно, нет поддержки для ситуаций, не связанных с TLS.
В поисках H2C
Это неправильный путь. Давайте подумаем о другом способе? Это флаг “h2c” в спецификации HTTP/2. Флаг “h2c” позволяет запускать протоколы HTTP/2 через протокол TCP с открытым текстом, который используется для обновления полей заголовка в HTTP/1.1 и идентификации HTTP/2 по протоколу TCP.
Но этот путь обсуждался в выпуске еще в 2015 году, когда @bradfitz дал понять, что @bradfitz не намерен поддерживать H2C и был очень доволен только поддержкой TLS. Я спросил снова год спустя. Первоначальный ответ выглядит следующим образом:
Мы не планируем поддерживать h2c. Я не хочу получать сообщения об ошибках от пользователей, которых кусают прозрачные прокси, связывающиеся с h2c. Кроме того, пока нет широкой поддержки браузера, это неинтересно. Я также не заинтересован в том, чтобы быть курицей или яйцом, чтобы получить поддержку браузера. Я очень доволен ситуацией только с TLS и такими вещами, как https://LetsEncrypt.org/скоро сделает TLS намного проще (и автоматически).
Спроси меня еще раз через год.
Подумайте о других способах
Использование cmux
Пробки/ grpc -пример шлюза-это альтернативная реализация, основанная на мультиплексоре soheilhy/cmux. Если да cmux Вы также можете увидеть Golang: Запуск нескольких служб на одном порту.
Используйте сторонние H2
- векрин/h2c
Этот вид логики принадлежит самому себе и реализует логику h2c, чтобы достичь эффекта.
Сейчас?
После непрерывного обсуждения в сообществе, в июне 2018 года, от имени логотипа “h2c” golang .org/x/net/http2/h2c Поскольку стандартная библиотека была официально объединена, мы можем использовать официальную стандартную библиотеку (h2c), которая реализует незашифрованный режим HTTP/2, поэтому мы можем использовать стандартную библиотеку для предоставления функций HTTP/1.1 и HTTP/2 на одном и том же порту.
Использование стандартной библиотеки H2C
import (
...
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"google.golang.org/grpc"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
pb "github.com/EDDYCJY/go-grpc-example/proto"
)
...
func grpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
return h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
grpcServer.ServeHTTP(w, r)
} else {
otherHandler.ServeHTTP(w, r)
}
}), &http2.Server{})
}
func main() {
server := grpc.NewServer()
pb.RegisterSearchServiceServer(server, &SearchService{})
mux := http.NewServeMux()
gwmux := runtime.NewServeMux()
dopts := []grpc.DialOption{grpc.WithInsecure()}
err := pb.RegisterSearchServiceHandlerFromEndpoint(context.Background(), gwmux, "localhost:"+PORT, dopts)
...
mux.Handle("/", gwmux)
http.ListenAndServe(":"+PORT, grpcHandlerFunc(server, mux))
}Мы видим, что ключ-это вызов. h2c. Новый обработчик Метод был специально обработан. h2c. Новый обработчик Вернет один http.обработчик Основная внутренняя логика заключается в том, чтобы перехватить все h2c Затем трафик перехватывается и перенаправляется на соответствующий трафик в соответствии с различными типами трафика запросов Хандер Иметь дело с.
Проверка
HTTP/1.1
$ curl -X GET 'http://127.0.0.1:9005/search?request=EDDYCJY'
{"response":"EDDYCJY"}HTTP/2(gRPC)
...
func main() {
conn, err := grpc.Dial(":"+PORT, grpc.WithInsecure())
...
client := pb.NewSearchServiceClient(conn)
resp, err := client.Search(context.Background(), &pb.SearchRequest{
Request: "gRPC",
})
}Выходные результаты:
$ go run main.go 2019/06/21 20:04:09 resp: gRPC h2c Server
резюме
В этой статье я представляю общие причины и следствия, а также несколько решений. Я предлагаю вам выбрать официальный. h2c Стандартная библиотека для реализации этой функции также проста. В конце концов, я надеюсь, что эта статья может помочь вам, независимо от того, беспокоила ли вас эта проблема в течение длительного времени или вы боретесь с ней.
Справочные ресурсы
- Справочные ресурсы
- Справочные ресурсы
- Справочные ресурсы
- https://go-review.googlesourc…
Оригинал: “https://developpaper.com/can-grpc-grpc-gateway-not-use-certificates/”