Tencentアーキテクト:自分でデバッグすると、インタビューがソースコードを尋ねる理由がわかります

SpringBootは巨大なpythonのようなもので、ゆっくりと私たちを巻き込み、麻痺させます。SpringBootを使用すると作業効率が向上することを認めざるを得ませんが、それによって多くのスキルを忘れてしまいます。私が最初に社会に入ったときも、Tomcatを介して手動でJavaWebプロジェクトをデプロイし、Tomcatでパフォーマンスチューニングを頻繁に実行していました。さらに、Jarの損失とバージョンの競合によって引き起こされる異常なサービス起動の問題を回避するために、Jar間の関係を明確にする必要もあります。これまで、これらの退屈で反復的なタスクはすべてSpringBootに引き継がれており、ビジネスロジックにさらに集中できます。ただし、Tomcatの動作原理とリクエストの処理プロセスを理解することは、Springフレームワークのソースコードを分析することと同じくらい重要です。少なくとも面接担当者は、これらの基本的な原則と設計のアイデアについて尋ねることを好みます。この記事があなたの助けになることを願っています。

機能コンポーネントの構造

Tomcatコネクタの中核となる原則

Tomcatコネクタフレームワーク-コヨーテ

コネクタコア機能

1.ネットワークポートを監視し、ネットワーク要求を受信して​​応答します。

2.ネットワークバイトストリーム処理。受信したネットワークバイトストリームをTomcatリクエストに変換し、次にコンテナーへの標準のServletRequestに変換します。同時に、コンテナーからのServletResponseをTomcatレスポンスに変換してから、ネットワークバイトストリームに変換します。

コネクタモジュールの設計

コネクタの2つのコア機能を満たすために、ポートを監視する通信エンドポイント、ネットワークバイトストリームを処理するプロセッサ、最後に、処理された結果をコンテナーが必要とする構造に変換するアダプターが必要です。

対応するソースコードパッケージパスorg.apache.coyote。対応する構造図は次のとおりです

Tomcatコンテナーのコア原則

Tomcatコンテナーフレームワーク-カタリナ

コンテナ構造分析

各サービスにはコンテナが含まれます。コンテナは、1つのエンジンで複数の仮想ホストを管理できます。各仮想ホストは複数のWebアプリケーションを管理できます。各Webアプリケーションには、複数のサーブレットラッパーがあります。エンジン、ホスト、コンテキスト、ラッパーの4つのコンテナは、親子関係に属しています。

対応するソースコードパッケージパスorg.apache.coyote。対応する構造図は次のとおりです

コンテナリクエスト処理

コンテナのリクエスト処理プロセスは、エンジン、ホスト、コンテキスト、ラッパーの4つのコンテナ間でレイヤーごとに呼び出され、最後に対応するビジネスロジックがサーブレットで実行されます。各コンテナにはチャネルパイプラインがあり、各チャネルにはリクエストとレスポンスの処理に使用されるゲートに似た基本バルブ(StandardEngineValveなど)があります。フローチャートは以下の通りです。

Tomcatリクエスト処理フロー

上記の知識ポイントにより、Tomcatがリクエストを処理する方法が少しずつ導入されました。簡単に理解すると、コネクタの処理フロー+コンテナの処理フロー= Tomcatの処理フローです。何!では、問題は、Tomcatがリクエストパスを介して対応する仮想サイトをどのように見つけるかということです。対応するサーブレットを見つける方法は?

マッパー機能紹介

ここでは、上記で説明されていないコンポーネントマッパーを導入する必要があります。名前が示すように、その役割はリクエストパスのルートマップを提供することです。リクエストに応じて、URLの一致はどのコンテナによって処理されます。これらの各コンテナーには、MappedHostなどの対応する独自のマッパーがあります。見つからないマッパークラスに支配されることへの恐怖を覚えているかどうかはわかりません。以前は、完全な関数を作成するたびに、web.xmlでマッピングルールを構成する必要があり、ファイルが大きくなると、さまざまな問題も発生します。

HTTPリクエストフロー

tomcat / confディレクトリのserver.xmlファイルを開いて、http:// localhost:8080 / docs / apiリクエストを分析します。

手順1:コネクタのリスニングポートは8080です。要求されたポートはリスニングポートと同じであるため、コネクタは要求を受け入れました。

ステップ2:エンジンのデフォルトの仮想ホストはlocalhostであり、仮想ホストのディレクトリはwebappsであるため。そのため、リクエストはtomcat / webappsディレクトリを見つけました。

ステップ3:解析されたドキュメントは、コンテキストであるWebプログラムのアプリケーション名です。この時点で、リクエストは引き続きwebappsディレクトリの下のdocsディレクトリを見つけます。また、アプリケーション名を省略することもあります。

ステップ4:解析されたAPIは特定のビジネスロジックアドレスです。このとき、docs / WEB-INF / web.xmlからマッピング関係を見つけ、最後に特定の関数を呼び出す必要があります。

<?xml version = "1.0" encoding = "UTF-8"?> 
<Server port = "8005" shutdown = "SHUTDOWN"> 

  <Service name = "Catalina"> 

	<!-コネクタのリスニングポートはデフォルトの8080です通信プロトコルはHTTP / 1.1-> 
    <Connector port = "8080" protocol = "HTTP / 1.1" 
               connectionTimeout = "20000" 
               redirectPort = "8443" /> 
			   
	<!-デフォルトの仮想ホストであるCatalinaという名前のエンジンこれはlocalhostです-> 
    <Engine name = "Catalina" defaultHost = "localhost"> 

	  <!-localhostという名前の仮想ホストで、そのディレクトリは
      webapps- > <Host name = "localhost" appBase = "webapps" 
            unpackWARs =です"true" autoDeploy = "true">

      </ Host> 
    </ Engine> 
  </ Service> 
</ Server>

SpringBootは組み込みTomcatをどのように起動しますか

SpringBootのワンクリックサービス開始機能は、社会に入ったばかりの多くの友人にTomcatが何であるかを忘れさせます。ハードウェアのパフォーマンスの向上に伴い、組み込みのTomcatを使用して、通常の中小規模のプロジェクトを直接開始できます。ただし、一部の大規模なプロジェクトではTomcatのクラスタリングとチューニングを使用している場合があり、組み込みのTomcatではニーズを満たせない場合があります。

まず、SpringBootがソースコードからTomcatを起動する方法を分析します以下はSpringBoot 2.xのコードです。

コードはmainメソッドから始まり、runメソッドを実行してプロジェクトを開始します。

SpringApplication.run

runメソッドからクリックして、アプリケーションコンテキストを更新する方法を見つけます。

this.prepareContext(コンテキスト、環境、リスナー、applicationArguments、printedBanner); 
this.refreshContext(context); 
this.afterRefresh(context、applicationArguments);

refreshContextメソッドからクリックして、refreshメソッドを見つけます。そして、その親クラスのメソッドをレイヤーごとに調べます。

this.refresh(context);

AbstractApplicationContextクラスのrefreshメソッドには、子コンテナの更新を呼び出すロジックの行があります。

this.postProcessBeanFactory(beanFactory); 
this.invokeBeanFactoryPostProcessors(beanFactory); 
this.registerBeanPostProcessors(beanFactory); 
this.initMessageSource(); 
this.initApplicationEventMulticaster(); 
this.onRefresh(); 
this.registerListeners(); 
this.finishBeanFactoryInitialization(beanFactory); 
this.finishRefresh();

onRefreshメソッドからクリックして、ServletWebServerApplicationContextの実装メソッドを見つけます。ここにようやく希望が見えます。

protected void onRefresh(){ 
    super.onRefresh(); 

    { 
        this.createWebServer();を試してください 
    } catch(Throwable var2){ 
        throw new ApplicationContextException( "Unable to start web server"、var2); 
    } 
}

createWebServerメソッドからクリックして、ファクトリクラスからWebServerを取得するコードを見つけます。

if(webServer == null && servletContext == null){ 
    ServletWebServerFactory factory = this.getWebServerFactory(); 
    // Webサーバーを
    取得しますthis.webServer = factory.getWebServer(new ServletContextInitializer [] {this.getSelfInitializer()}); 
} else if(servletContext!= null){ 
    try { 
        // 
        启动Webサーバーthis.getSelfInitializer()。onStartup(servletContext); 
    } catch(ServletException var4){ 
        throw new ApplicationContextException( "Cannot initialize servlet context"、var4); 
    } 
}

getWebServerメソッドからクリックして、JettyとUndertowに対応するTomcatServletWebServerFactoryの実装メソッドを見つけます。基本的なコネクタ、エンジン、仮想サイト、およびその他の構成は、ここで構成されます。

public WebServer getWebServer(ServletContextInitializer ... initializers){ 
    Tomcat tomcat = new Tomcat(); 
    ファイルbaseDir = this.baseDirectory!= null?this.baseDirectory:this.createTempDir( "tomcat"); 
    tomcat.setBaseDir(baseDir.getAbsolutePath()); 
    コネクター・コネクター=新しいコネクター(this.protocol); 
    tomcat.getService()。addConnector(connector); 
    this.customizeConnector(connector); 
    tomcat.setConnector(connector); 
    tomcat.getHost()。setAutoDeploy(false); 
    this.configureEngine(tomcat.getEngine()); 
    イテレーターvar5 = this.additionalTomcatConnectors.iterator(); 

    while(var5.hasNext()){ 
        Connector additionalConnector =(Connector)var5.next();
        tomcat.getService()。addConnector(additionalConnector); 
    } 

    this.prepareContext(tomcat.getHost()、initializers); 
    this.getTomcatWebServer(tomcat);を返します。
}

ログはサービスの開始後に印刷されます

osbwembedded.tomcat.TomcatWebServer:ポートで初期化されたTomcat:8900(http)
o.apache.catalina.core.StandardService:サービスの開始[Tomcat] 
org.apache.catalina.core.StandardEngine:サーブレットエンジンの開始:Apache Tomcat / 8.5.34 
oacatalina.core.AprLifecycleListener:最適化を可能にするAPRベースのApache Tomcatネイティブライブラリ... 
oaccC [Tomcat]。[localhost]。[/]:Spring組み込みWebApplicationContextの初期化
osweb.context.ContextLoader:ルートWebApplicationContext:初期化が完了しました16858ミリ秒

最も強力な企業がテクノロジーの基礎となるソースコードについて尋ねる理由を発見したような気がします。ソースコードを見るプロセスは非常に興味深いものであり、多くの問題が見つかり、論理的な思考と忍耐力を実際にテストします。 Tomcatのソースコードを見てみましょう。1日が経過しましたが、まだ完了していません。これは、Tomcatに精通していることを前提としています。はははは、私に注意してください。時間があれば、後で更新します。

 

最後に、ドキュメントを紹介します。これは、Tomcatの分析プロセスで最もよく参照する本でもあります。内部知識は、基本的に、Tomcatの関連コンテンツ(アーキテクチャの設計から構成、クラスタリング、パフォーマンスの最適化や拡張など)、Tomcatの包括的な分析をカバーしています、困っている友達は+をフォローした後、プライベートメッセージの「ソースコード」を取得して取得方法を表示できます。

Tomcatアーキテクチャ

Tomcat構成管理

tomcatセキュリティ

Tomcatチューニング

tomcatの追加機能

 

スペース上の理由から、この部分のみが表示されます。Java関連の学習ドキュメントやビデオがさらに必要な場合は、私に従ってください。バックグラウンドでプライベートメッセージング「データ」を使用して取得できます

公開番号:Java Architects Alliance、メディア更新テクノロジーに関する優れた記事

 

おすすめ

転載: blog.csdn.net/weixin_42864905/article/details/108731189