Skip to content
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

[spacetime] Http/2 support #123748

Closed
wants to merge 13 commits into from
Closed

[spacetime] Http/2 support #123748

wants to merge 13 commits into from

Conversation

mshustov
Copy link
Contributor

@mshustov mshustov commented Jan 25, 2022

Summary

parent issue #7104
This PR attempts to estimate the effort of adding HTTP/2 support to the Kibana web server.
Note that the change won't improve load time on Cloud. Kibana browser app already connects to the Cloud proxy via http2. Cloud proxy converses http/2 into http/1 to communicate with the Kibana server though.

Why

HTTP/2 protocol is multiplexed, so the browser will use a single connection for parallelism. Kibana, in the current implementation, reforms about 200 requests to the Kibana server on start. Web browsers limit the number of parallel connections to six per domain. Therefore, the requests are stuck in a queue, and Kibana has sub-optimal UX for a high number of parallel requests to the Kibana server. To work the problem around we use different techniques like long-term caching and request batching. Both have critical problems. Caching might be disabled or periodically cleared on a client. Request batching adds additional overhead. Using HTTP/2 makes these workarounds obsolete.

TODO

  • to check compatibility with a request proxy in Console app
  • to verify whether switching to http/2 will affect other Stack components interacting with Kibana: fleet, filebeats, etc.
  • to verify APM agent supports http/2. It supports http/2 protocol https://github.com/elastic/apm-agent-nodejs/blob/main/lib/instrumentation/modules/http2.js
  • check whether it's possible to use outdated superagent and supertest in the integration tests or they need to be updated to the latest versions with http/2 support
  • perform load testing to measure impact on the Kibana server.

Performance impact

on the loading time

Tested on e2-standard-4 instance on gcp in europe-west2-a zone via lighthouse, landing on /home page
main branch
2022-01-25_19-05-55
PR
2022-01-25_19-07-09

Known problems

The full list of incompatibilities between http/1 and http/2 in node nodejs/node#29829

@mshustov mshustov added Feature:http Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc labels Jan 25, 2022
@@ -7,11 +7,12 @@
*/

export function pick<T extends object, K extends keyof T>(obj: T, keys: readonly K[]): Pick<T, K> {
return keys.reduce((acc, key) => {
if (obj.hasOwnProperty(key)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the case of http/2, headers object is created via Object.create(null) so it hasn't got hasOwnProperty method

@@ -67,11 +66,11 @@ export interface ReqOptions {
path: string;
query?: Record<string, any>;
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
body?: any;
body?: Record<string, any> | string;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: check whether we use string anywhere

@kibana-ci
Copy link
Collaborator

kibana-ci commented Jan 27, 2022

💔 Build Failed

Failed CI Steps

Test Failures

  • [job] [logs] OSS Accessibility Tests / a11y tests using flights sample data "after all" hook in "using flights sample data"
  • [job] [logs] OSS Accessibility Tests / a11y tests using flights sample data "after all" hook in "using flights sample data"
  • [job] [logs] Default CI Group #2 / Advanced Settings security feature controls global advanced_settings all privileges "before all" hook for "shows management navlink"
  • [job] [logs] Default CI Group #2 / Advanced Settings security feature controls global advanced_settings all privileges "before all" hook for "shows management navlink"
  • [job] [logs] Default CI Group #17 / alerting api integration security and spaces enabled Actions "after all" hook in "Actions"
  • [job] [logs] Default CI Group #17 / alerting api integration security and spaces enabled Actions "after all" hook in "Actions"
  • [job] [logs] API Integration Tests / apis KQL telemetry API "after all" hook for "should only accept literal boolean values for the opt_in POST body param"
  • [job] [logs] API Integration Tests / apis KQL telemetry API "before all" hook for "should increment the opt in counter in the .kibana/kql-telemetry document"
  • [job] [logs] Default CI Group #18 / apis Monitoring Setup Collection detect_logstash_management "after all" hook: unload archive for "should get collection status"
  • [job] [logs] Default CI Group #18 / apis Monitoring Setup Collection detect_logstash_management "after all" hook: unload archive for "should get collection status"
  • [job] [logs] Default CI Group #18 / apis Monitoring Setup Collection detect_logstash_management "before all" hook: load archive for "should get collection status"
  • [job] [logs] Default CI Group #18 / apis Monitoring Setup Collection detect_logstash_management "before all" hook: load archive for "should get collection status"
  • [job] [logs] Default CI Group #11 / apis SecuritySolution Endpoints basic licsense cases feature privilege "after each" hook for "User sec_all_user with role(s) sec_all_role can create a case"
  • [job] [logs] Default CI Group #11 / apis SecuritySolution Endpoints basic licsense cases feature privilege "after each" hook for "User sec_all_user with role(s) sec_all_role can create a case"
  • [job] [logs] Default Firefox Tests / Canvas app "after all" hook: afterTestSuite.trigger in "Canvas app"
  • [job] [logs] Default Firefox Tests / Canvas app "after all" hook: afterTestSuite.trigger in "Canvas app"
  • [job] [logs] Default Firefox Tests / Canvas app smoke test "after all" hook for "renders elements on workpad"
  • [job] [logs] Default Firefox Tests / Canvas app smoke test "after all" hook for "renders elements on workpad"
  • [job] [logs] Default Firefox Tests / Canvas app smoke test "before all" hook for "loads workpad list"
  • [job] [logs] Default Firefox Tests / Canvas app smoke test "before all" hook for "loads workpad list"
  • [job] [logs] Default CI Group #27 / cases security and spaces enabled: basic push_case "after each" hook for "should get 403 when trying to create a connector"
  • [job] [logs] Default CI Group #27 / cases security and spaces enabled: basic push_case "after each" hook for "should get 403 when trying to create a connector"
  • [job] [logs] OSS Firefox Tests / console app "after all" hook: afterTestSuite.trigger in "console app"
  • [job] [logs] OSS Firefox Tests / console app "after all" hook: afterTestSuite.trigger in "console app"
  • [job] [logs] OSS CI Group #1 / context app "after all" hook in "context app"
  • [job] [logs] OSS CI Group #1 / context app "after all" hook in "context app"
  • [job] [logs] OSS CI Group #1 / context app "before all" hook in "context app"
  • [job] [logs] OSS CI Group #1 / context app "before all" hook in "context app"
  • [job] [logs] OSS Misc Functional Tests / core deprecations service Public API "before all" hook for "#getAllDeprecations returns all deprecations plugin deprecations"
  • [job] [logs] OSS Misc Functional Tests / core deprecations service Public API "before all" hook for "#getAllDeprecations returns all deprecations plugin deprecations"
  • [job] [logs] Jest Tests #5 / createPluginInitializerContext context.config config.globalConfig$ should be an observable for the global config
  • [job] [logs] OSS CI Group #6 / dashboard app new charts library dashboard state "after all" hook for "Saved search will update when the query is changed in the URL"
  • [job] [logs] OSS CI Group #6 / dashboard app new charts library dashboard state "after all" hook for "Saved search will update when the query is changed in the URL"
  • [job] [logs] OSS CI Group #6 / dashboard app new charts library dashboard state "before all" hook for "Overriding colors on an area chart is preserved"
  • [job] [logs] OSS CI Group #6 / dashboard app new charts library dashboard state "before all" hook for "Overriding colors on an area chart is preserved"
  • [job] [logs] OSS CI Group #2 / dashboard app using current data empty dashboard "after all" hook for "should open editor menu when editor button is clicked"
  • [job] [logs] OSS CI Group #2 / dashboard app using current data empty dashboard "after all" hook for "should open editor menu when editor button is clicked"
  • [job] [logs] OSS CI Group #2 / dashboard app using current data empty dashboard "before all" hook for "should display empty widget"
  • [job] [logs] OSS CI Group #2 / dashboard app using current data empty dashboard "before all" hook for "should display empty widget"
  • [job] [logs] OSS CI Group #3 / dashboard app using current data full screen mode "before all" hook for "option not available in edit mode"
  • [job] [logs] OSS CI Group #3 / dashboard app using current data full screen mode "before all" hook for "option not available in edit mode"
  • [job] [logs] OSS CI Group #5 / dashboard app using legacy data dashboard save "before all" hook for "warns on duplicate name for new dashboard"
  • [job] [logs] OSS CI Group #5 / dashboard app using legacy data dashboard save "before all" hook for "warns on duplicate name for new dashboard"
  • [job] [logs] OSS CI Group #4 / dashboard app using legacy data dashboard time picker "after all" hook for "Timepicker respects dateFormat from UI settings"
  • [job] [logs] OSS CI Group #4 / dashboard app using legacy data dashboard time picker "after all" hook for "Timepicker respects dateFormat from UI settings"
  • [job] [logs] OSS CI Group #4 / dashboard app using legacy data dashboard time picker "before all" hook for "Visualization updated when time picker changes"
  • [job] [logs] OSS CI Group #4 / dashboard app using legacy data dashboard time picker "before all" hook for "Visualization updated when time picker changes"
  • [job] [logs] OSS CI Group #10 / dashboard elements dashboard elements ciGroup10 input controls input control options "before all" hook for "should not have inspector enabled"
  • [job] [logs] OSS CI Group #10 / dashboard elements dashboard elements ciGroup10 input controls input control options "before all" hook for "should not have inspector enabled"
  • [job] [logs] Default CI Group #19 / dashboard feature controls dashboard feature controls security "after all" hook in "dashboard feature controls security"
  • [job] [logs] Default CI Group #19 / dashboard feature controls dashboard feature controls security "after all" hook in "dashboard feature controls security"
  • [job] [logs] Default CI Group #19 / dashboard feature controls dashboard feature controls security "before all" hook in "dashboard feature controls security"
  • [job] [logs] Default CI Group #19 / dashboard feature controls dashboard feature controls security "before all" hook in "dashboard feature controls security"
  • [job] [logs] Default CI Group #13 / Dev Tools feature controls security "before all" hook in "security"
  • [job] [logs] Default CI Group #13 / Dev Tools feature controls security "before all" hook in "security"
  • [job] [logs] Default CI Group #25 / discover preserve url "after all" hook for "remembers url after switching spaces"
  • [job] [logs] Default CI Group #25 / discover preserve url "after all" hook for "remembers url after switching spaces"
  • [job] [logs] Default CI Group #25 / discover preserve url "before all" hook for "goes back to last opened url"
  • [job] [logs] Default CI Group #25 / discover preserve url "before all" hook for "goes back to last opened url"
  • [job] [logs] Docker CI Group / endpoint "before all" hook in "endpoint"
  • [job] [logs] Docker CI Group / endpoint "before all" hook in "endpoint"
  • [job] [logs] Default CI Group #12 / graph app feature controls spaces "before all" hook in "spaces"
  • [job] [logs] Default CI Group #12 / graph app feature controls spaces "before all" hook in "spaces"
  • [job] [logs] Jest Tests #5 / has defaults for config
  • [job] [logs] Default Accessibility Tests / Kibana overview "after all" hook for "Kibana overview"
  • [job] [logs] Default Accessibility Tests / Kibana overview "after all" hook for "Kibana overview"
  • [job] [logs] Default Accessibility Tests / Kibana overview "before all" hook for "Kibana overview"
  • [job] [logs] Default Accessibility Tests / Kibana overview "before all" hook for "Kibana overview"
  • [job] [logs] Jest Tests #5 / Legacy config getGlobalConfig should return the global config
  • [job] [logs] Jest Tests #5 / Legacy config getGlobalConfig$ should return an observable for the global config
  • [job] [logs] Default CI Group #3 / lens app "after all" hook in "lens app"
  • [job] [logs] Default CI Group #16 / lens app "after all" hook in "lens app"
  • [job] [logs] Default CI Group #3 / lens app "after all" hook in "lens app"
  • [job] [logs] Default CI Group #16 / lens app "after all" hook in "lens app"
  • [job] [logs] Default CI Group #3 / lens app "before all" hook in "lens app"
  • [job] [logs] Default CI Group #16 / lens app "before all" hook in "lens app"
  • [job] [logs] Default CI Group #3 / lens app "before all" hook in "lens app"
  • [job] [logs] Default CI Group #16 / lens app "before all" hook in "lens app"
  • [job] [logs] Default CI Group #26 / machine learning anomaly detection single metric "after all" hook for "deletes the cloned job"
  • [job] [logs] Default CI Group #26 / machine learning anomaly detection single metric "after all" hook for "deletes the cloned job"
  • [job] [logs] Default CI Group #15 / machine learning permissions for user with full ML access with data loaded "after all" hook in "with data loaded"
  • [job] [logs] Default CI Group #15 / machine learning permissions for user with full ML access with data loaded "after all" hook in "with data loaded"
  • [job] [logs] Default CI Group #8 / machine learning settings calendar creation "after all" hook for "creates new calendar that applies to specific jobs"
  • [job] [logs] Default CI Group #8 / machine learning settings calendar creation "after all" hook for "creates new calendar that applies to specific jobs"
  • [job] [logs] OSS CI Group #9 / management "Create Index Pattern" wizard "before all" hook in ""Create Index Pattern" wizard"
  • [job] [logs] OSS CI Group #9 / management "Create Index Pattern" wizard "before all" hook in ""Create Index Pattern" wizard"
  • [job] [logs] OSS CI Group #8 / management index pattern filter "before all" hook for "should filter indexed fields"
  • [job] [logs] OSS CI Group #8 / management index pattern filter "before all" hook for "should filter indexed fields"
  • [job] [logs] Default CI Group #10 / maps app "after all" hook in "maps app"
  • [job] [logs] Default CI Group #22 / maps app "after all" hook in "maps app"
  • [job] [logs] Default CI Group #22 / maps app "after all" hook in "maps app"
  • [job] [logs] Default CI Group #9 / maps app "after all" hook in "maps app"
  • [job] [logs] Default CI Group #10 / maps app "after all" hook in "maps app"
  • [job] [logs] Default CI Group #9 / maps app "after all" hook in "maps app"
  • [job] [logs] Default CI Group #10 / maps app "before all" hook in "maps app"
  • [job] [logs] Default CI Group #22 / maps app "before all" hook in "maps app"
  • [job] [logs] Default CI Group #22 / maps app "before all" hook in "maps app"
  • [job] [logs] Default CI Group #9 / maps app "before all" hook in "maps app"
  • [job] [logs] Default CI Group #10 / maps app "before all" hook in "maps app"
  • [job] [logs] Default CI Group #9 / maps app "before all" hook in "maps app"
  • [job] [logs] Default CI Group #1 / Monitoring app feature controls security "after all" hook in "security"
  • [job] [logs] Default CI Group #1 / Monitoring app feature controls security "after all" hook in "security"
  • [job] [logs] Default CI Group #1 / Monitoring app feature controls security "before all" hook in "security"
  • [job] [logs] Default CI Group #1 / Monitoring app feature controls security "before all" hook in "security"
  • [job] [logs] Jest Tests #5 / response headers allows to configure "keep-alive" header
  • [job] [logs] OSS CI Group #7 / saved objects management saved objects inspect page allows to view the saved object
  • [job] [logs] OSS CI Group #7 / saved objects management saved objects inspect page allows to view the saved object
  • [job] [logs] Default CI Group #20 / saved objects security and spaces enabled _bulk_create user with no access within the default space "after all" hook for "should return 403 forbidden [hiddentype/any]"
  • [job] [logs] Default CI Group #20 / saved objects security and spaces enabled _bulk_create user with no access within the default space "after all" hook for "should return 403 forbidden [hiddentype/any]"
  • [job] [logs] Default CI Group #20 / saved objects security and spaces enabled _bulk_create user with no access within the default space "before all" hook for "should return 403 forbidden [isolatedtype/defaultspace-isolatedtype-id]"
  • [job] [logs] Default CI Group #20 / saved objects security and spaces enabled _bulk_create user with no access within the default space "before all" hook for "should return 403 forbidden [isolatedtype/defaultspace-isolatedtype-id]"
  • [job] [logs] Default CI Group #14 / saved objects tagging - functional tests table listing "after all" hook in "table listing"
  • [job] [logs] Default CI Group #14 / saved objects tagging - functional tests table listing "after all" hook in "table listing"
  • [job] [logs] Default CI Group #14 / saved objects tagging - functional tests table listing "before all" hook in "table listing"
  • [job] [logs] Default CI Group #14 / saved objects tagging - functional tests table listing "before all" hook in "table listing"
  • [job] [logs] Default CI Group #7 / security app Security Login Page "after all" hook for "displays message acknowledging logout"
  • [job] [logs] Default CI Group #7 / security app Security Login Page "after all" hook for "displays message acknowledging logout"
  • [job] [logs] Default CI Group #7 / security app Security Login Page "before all" hook for "can login"
  • [job] [logs] Default CI Group #7 / security app Security Login Page "before all" hook for "can login"
  • [job] [logs] Default CI Group #4 / Spaces app Copy Saved Objects to Space "after all" hook for "allows a dashboard to be copied to the marketing space, with circular references"
  • [job] [logs] Default CI Group #4 / Spaces app Copy Saved Objects to Space "after all" hook for "allows a dashboard to be copied to the marketing space, with circular references"
  • [job] [logs] Default CI Group #4 / Spaces app Copy Saved Objects to Space "before all" hook for "allows a dashboard to be copied to the marketing space, with all references"
  • [job] [logs] Default CI Group #4 / Spaces app Copy Saved Objects to Space "before all" hook for "allows a dashboard to be copied to the marketing space, with all references"
  • [job] [logs] Default CI Group #21 / transform feature controls security "after all" hook in "security"
  • [job] [logs] Default CI Group #21 / transform feature controls security "after all" hook in "security"
  • [job] [logs] Default CI Group #21 / transform feature controls security "before all" hook in "security"
  • [job] [logs] Default CI Group #21 / transform feature controls security "before all" hook in "security"
  • [job] [logs] Default CI Group #6 / Uptime app with real-world data "before all" hook in "with real-world data"
  • [job] [logs] Default CI Group #6 / Uptime app with real-world data "before all" hook in "with real-world data"
  • [job] [logs] OSS CI Group #11 / visualize app visualize ciGroup11 tag cloud chart "before all" hook for "should have inspector enabled"
  • [job] [logs] OSS CI Group #11 / visualize app visualize ciGroup11 tag cloud chart "before all" hook for "should have inspector enabled"

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/server-http-tools 50 51 +1

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
kbnUiSharedDeps-srcJs 3.8MB 3.8MB +20.0B
Unknown metric groups

API count

id before after diff
@kbn/server-http-tools 53 54 +1

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@Dosant
Copy link
Contributor

Dosant commented Feb 2, 2022

bfetch can be refactored to support http/2. Maybe we don't need it at all and can fall back to the plain HTTP call? HTTP/2 hasn't got limits on the number of parallel requests to a single domain.

@mshustov, I was thinking about this and thought that maybe there is not much benefit in having bfetch layer with HTTP/2, so added a configuration to not use it for search: #122244 so we could test the difference in cloud.

I thought that would be a good experiment because I saw h2 connection in cloud, but I completely missed that h2 connection is just between client and proxy 🤦‍♂️

TIL that's a lot more complicated

@rudolf
Copy link
Contributor

rudolf commented Jan 24, 2023

Closing as stale PR

@rudolf rudolf closed this Jan 24, 2023
pgayvallet added a commit that referenced this pull request May 17, 2024
…183697)

## Summary

Related to #7104
Extracted from #123748

`http2` headers are created via `Object.create(null)`, which causes
issues with the way our `pick` method was implemented. PR fixes it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:http Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants