خادم مدمج مع إعادة تحميل التعليمات البرمجية المخصصة وسجلات sql بواسطة فريق مخضرم واحد من أجل التطوير الإنتاجي

أود أن أشارك تجربة استخدام payara-micro في تطوير تطبيقات المؤسسة. آمل أن يوفر شخص ما الوقت ، لأن هذا القرار لم يأت على الفور. إذا كنت تستخدم بالفعل Payara أو Glassfish كخادم صناعي ، أو ستغرق فقط في عالم javaee ، فإن payara-micro وهذه المقالة لك.


ستحتاج إلى تطبيق ويب ، يتم تجميعه من خلال مخضرم في أرشيف حرب ، وجافا 8 (لم يتم التحقق من التطبيقات القديمة).


أولاً ، سأعطي النص الكامل للملف الشخصي ، وبعد ذلك سنقوم بتحليله إلى أجزاء وإضافة التفاصيل المفقودة غير المرئية في شفرة المصدر.


الملف الشخصي مخضرم ل payara-micro
<profile> <id>micro</id> <build> <plugins> <plugin> <artifactId>maven-dependency-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>copy-payara-micro</id> <phase>package</phase> <goals> <goal>copy</goal> </goals> <configuration> <outputDirectory>${project.build.directory}</outputDirectory> <stripVersion>true</stripVersion> <silent>true</silent> <artifactItems> <artifactItem> <groupId>fish.payara.extras</groupId> <artifactId>payara-micro</artifactId> <type>jar</type> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> <cut/> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <goals> <goal>exec</goal> </goals> </execution> </executions> <configuration> <executable>java</executable> <arguments> <!--http://blog.payara.fish/using-hotswapagent-to-speed-up-development--> <argument>-XXaltjvm=dcevm</argument> <argument>-javaagent:hotswap/hotswap-agent.jar</argument> <argument>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9009</argument> <argument>-Duser.language=en</argument> <argument>-Duser.region=US</argument> <argument>-Ddb.ora.url=jdbc:p6spy:oracle:thin:@localhost:1521:XE</argument> <argument>-Ddb.pg.url=jdbc:p6spy:postgresql://localhost:5432/postgres</argument> <argument>-jar</argument> <argument>${project.build.directory}/${project.build.finalName}-microbundle.jar</argument> <!--<argument>&#45;&#45;prebootcommandfile</argument>--> <!--<argument>src/main/setup/payara-micro-domain-config.txt</argument>--> <argument>--domainConfig</argument> <argument>src/main/setup/domain.xml</argument> <argument>--deploy</argument> <argument>${project.build.directory}/${project.build.finalName}.war</argument> <argument>--rootDir</argument> <argument>${project.build.directory}/payaramicro</argument> </arguments> </configuration> </plugin> <plugin> <groupId>fish.payara.maven.plugins</groupId> <artifactId>payara-micro-maven-plugin</artifactId> <version>1.0.0</version> <executions> <execution> <goals> <goal>bundle</goal> <goal>start</goal> </goals> </execution> </executions> <configuration> <payaraVersion>4.1.2.173</payaraVersion> <autoDeployArtifact>false</autoDeployArtifact> <customJars> <artifactItem> <groupId>p6spy</groupId> <artifactId>p6spy</artifactId> <version>2.3.1</version> </artifactItem> <artifactItem> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.3</version> </artifactItem> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.2.0</version> </dependency> </customJars> </configuration> </plugin> </plugins> </build> <cut/> <dependencies> <dependency> <groupId>fish.payara.extras</groupId> <artifactId>payara-micro</artifactId> <version>4.1.2.173</version> <scope>provided</scope> </dependency> <dependency> <groupId>p6spy</groupId> <artifactId>p6spy</artifactId> <version>2.3.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.3</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.2.0</version> <scope>provided</scope> </dependency> </dependencies> </profile> 

أول ما عليك فعله هو تنزيل أرشيف payara-micro نفسه. هذا هو بالضبط ما يفعله المكون الإضافي الأول ( maven-اعتمادية- plugin ). الأرشيف هو خادم تطبيق كامل يمكن تشغيله من سطر الأوامر كتطبيق جافا بسيط.


لا يحتوي أحدث مكون إضافي ( payara-micro-maven-plugin ) على ميزات وتم تكوينه لإصدار عمل مستقر من payra-micro 4.1.2.173 . من إمكانات المكون الإضافي ، يتم استخدام وظيفة تعبئة تطبيق الويب في حزمة خاصة ، جاهزة للتشغيل ، هنا. هناك طرق أخرى لإطلاق payara-micro ، ولكن هنا ليست مفيدة لنا.


يبقى إنشاء سطر الأوامر المطلوب وتجميع كل شيء. يتم استخدام exec-maven-plugin للبدء من سطر الأوامر. دعونا نلقي نظرة فاحصة على معلمات سطر الأوامر:


 <configuration> <executable>java</executable> <arguments> <!--http://blog.payara.fish/using-hotswapagent-to-speed-up-development--> <argument>-XXaltjvm=dcevm</argument> <argument>-javaagent:hotswap/hotswap-agent.jar</argument> <argument>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9009</argument> <argument>-Duser.language=en</argument> <argument>-Duser.region=US</argument> <argument>-Ddb.ora.url=jdbc:p6spy:oracle:thin:@localhost:1521:XE</argument> <argument>-Ddb.pg.url=jdbc:p6spy:postgresql://localhost:5432/postgres</argument> <argument>-jar</argument> <argument>${project.build.directory}/${project.build.finalName}-microbundle.jar</argument> <argument>--domainConfig</argument> <argument>src/main/setup/domain.xml</argument> <argument>--deploy</argument> <argument>${project.build.directory}/${project.build.finalName}.war</argument> <argument>--rootDir</argument> <argument>${project.build.directory}/payaramicro</argument> </arguments> </configuration> 

هناك حاجة إلى الوسيطتين الأوليين ( -XXaltjvm = dcevm -javaagent: hotswap / hotswap-agent.jar ) لتغيير التعليمات البرمجية المصدر دون إعادة تشغيل التطبيق. بفضل الوسيطة الثانية ( -agentlib: jdwp = transport = dt_socket، server = y، suspend = n، address = 9009 ) ، نطلق التطبيق على الفور في وضع التصحيح ، مما يسمح لنا بتغيير ليس فقط من الأساليب نفسها من خلال وسائل تطبيق تغييرات التعليمات البرمجية في التصحيح في IDE ، ولكن أيضًا إضافة حقول جديدة والمزيد. ما عليك سوى الاتصال مع المصحح من IDE ، وتجميع ملف المصدر المعدل وتطبيق التغييرات.


الوسيطتان التاليتان (-Duser.language = ar -Duser.region = US ) مطلوبتان لعمل عميل jdbc بشكل صحيح مع Oracle. يتم تمرير إعدادات الاتصال بنظام DBMS التجريبي من خلال الوسائط -D . في تطبيقاتي ، أستخدم رابطًا مثل $ {db.ora.url} لهذه المعلمات في ملف المورد ، الذي ينشئها تلقائيًا عند بدء التشغيل. يتم أيضًا استبدال الملف الذي ينشئ موارد باستخدام إعدادات اختبار أو إعدادات صناعية من خلال ملف التعريف في مخضرم وقدرته على تصفية الملفات النصية.


تشير الوسيطات الرئيسية عند بدء التشغيل إلى المسار ( --domainConfig src / main / setup / domain.xml ) إلى ملف إعدادات النطاق ، بالإضافة إلى المسار إلى ملف الحرب (- نشر $ {project.build.directory} / $ {المشروع. build.finalName} .war ) ليتم نشرها على الخادم. حصلت على إعدادات النطاق بناءً على ملف قياسي داخل الأرشيف. سأعطي المحتويات كمثال. للاستخدام في تطوير هذه الإعدادات هو أكثر من كاف.


domain.xml
 <!-- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved. The contents of this file are subject to the terms of either the GNU General Public License Version 2 only ("GPL") or the Common Development and Distribution License("CDDL") (collectively, the "License"). You may not use this file except in compliance with the License. You can obtain a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html or packager/legal/LICENSE.txt. See the License for the specific language governing permissions and limitations under the License. When distributing the software, include this License Header Notice in each file and include the License file at packager/legal/LICENSE.txt. GPL Classpath Exception: Oracle designates this particular file as subject to the "Classpath" exception as provided by Oracle in the GPL Version 2 section of the License file that accompanied this code. Modifications: If applicable, add the following below the License Header, with the fields enclosed by brackets [] replaced by your own identifying information: "Portions Copyright [year] [name of copyright owner]" Contributor(s): If you wish your version of this file to be governed by only the CDDL or only the GPL Version 2, indicate your decision by adding "[Contributor] elects to include this software in this distribution under the [CDDL or GPL Version 2] license." If you don't indicate a single choice of license, a recipient has the option to distribute your version of this file under either the CDDL, the GPL Version 2 or to extend the choice of license to its licensees as provided above. However, if you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then the option applies only if the new code is made subject to such option by the copyright holder. Portions Copyright [2016] [Payara Foundation and/or its affiliates] --> <domain log-root="${com.sun.aas.instanceRoot}/logs" application-root="${com.sun.aas.instanceRoot}/applications" version="10.0"> <security-configurations> <authorization-service default="true" name="authorizationService"> <security-provider name="simpleAuthorization" type="Simple" provider-name="simpleAuthorizationProvider"> <authorization-provider-config support-policy-deploy="false" name="simpleAuthorizationProviderConfig"></authorization-provider-config> </security-provider> </authorization-service> </security-configurations> <system-applications /> <applications /> <resources> <jdbc-resource pool-name="DerbyPool" jndi-name="jdbc/__default" object-type="system-all" /> <jdbc-connection-pool is-isolation-level-guaranteed="false" name="DerbyPool" datasource-classname="org.apache.derby.jdbc.EmbeddedDataSource" res-type="javax.sql.DataSource"> <property name="databaseName" value="${com.sun.aas.instanceRoot}/lib/databases/embedded_default" /> <property name="connectionAttributes" value=";create=true" /> </jdbc-connection-pool> <context-service description="context service" jndi-name="concurrent/__defaultContextService" object-type="system-all"></context-service> <managed-executor-service maximum-pool-size="200" core-pool-size="6" long-running-tasks="true" keep-alive-seconds="300" hung-after-seconds="300" task-queue-capacity="20000" jndi-name="concurrent/__defaultManagedExecutorService" object-type="system-all"></managed-executor-service> <managed-scheduled-executor-service core-pool-size="6" long-running-tasks="true" keep-alive-seconds="300" hung-after-seconds="300" jndi-name="concurrent/__defaultManagedScheduledExecutorService" object-type="system-all"></managed-scheduled-executor-service> <managed-thread-factory description="thread factory" jndi-name="concurrent/__defaultManagedThreadFactory" object-type="system-all"></managed-thread-factory> </resources> <servers> <server name="server" config-ref="server-config"> <resource-ref ref="jdbc/__default" /> </server> </servers> <configs> <config name="server-config"> <health-check-service-configuration enabled="false"> <log-notifier enabled="true"/> <eventbus-notifier enabled="false"/> <cpu-usage-checker unit="MINUTES" name="CPU" time="1" enabled="true" /> <machine-memory-usage-checker unit="MINUTES" name="MMEM" time="3" enabled="true" /> <heap-memory-usage-checker unit="MINUTES" name="HEAP" time="3" enabled="true" /> <hogging-threads-checker unit="MINUTES" name="HT" time="5" enabled="true" /> <garbage-collector-checker unit="MINUTES" name="GC" time="5" enabled="true" /> </health-check-service-configuration> <http-service access-logging-enabled="false"> <access-log format="%client.name% %auth-user-name% %datetime% %request% %status% %response.length%" rotation-interval-in-minutes="15" rotation-suffix="yyyy-MM-dd"></access-log> <virtual-server id="server" access-logging-enabled="false" access-log="" network-listeners="http-listener, https-listener"></virtual-server> </http-service> <iiop-service> <orb use-thread-pool-ids="thread-pool-1"></orb> <iiop-listener id="orb-listener-1" enabled="false" address="0.0.0.0"></iiop-listener> </iiop-service> <admin-service system-jmx-connector-name="system" type="das-and-server"> <jmx-connector port="8686" address="0.0.0.0" security-enabled="false" auth-realm-name="admin-realm" name="system" enabled="false"></jmx-connector> <das-config></das-config> </admin-service> <connector-service class-loading-policy="global" shutdown-timeout-in-seconds="30"> </connector-service> <!--<ejb-container steady-pool-size="0" max-pool-size="32" session-store="${com.sun.aas.instanceRoot}/session-store" pool-resize-quantity="8">--> <!--<ejb-timer-service ejb-timer-service="Hazelcast"></ejb-timer-service>--> <!--</ejb-container>--> <log-service file="${com.sun.aas.instanceRoot}/logs/server.log" log-rotation-limit-in-bytes="2000000"> <module-log-levels /> </log-service> <security-service activate-default-principal-to-role-mapping="true" jacc="simple"> <auth-realm classname="com.sun.enterprise.security.auth.realm.file.FileRealm" name="admin-realm"> <property value="${com.sun.aas.instanceRoot}/config/admin-keyfile" name="file" /> <property value="fileRealm" name="jaas-context" /> </auth-realm> <auth-realm classname="com.sun.enterprise.security.auth.realm.file.FileRealm" name="file"> <property value="${com.sun.aas.instanceRoot}/config/keyfile" name="file" /> <property value="fileRealm" name="jaas-context" /> </auth-realm> <auth-realm classname="com.sun.enterprise.security.auth.realm.certificate.CertificateRealm" name="certificate" /> <jacc-provider policy-configuration-factory-provider="com.sun.enterprise.security.provider.PolicyConfigurationFactoryImpl" policy-provider="com.sun.enterprise.security.provider.PolicyWrapper" name="default"> <property value="${com.sun.aas.instanceRoot}/generated/policy" name="repository" /> </jacc-provider> <jacc-provider policy-configuration-factory-provider="com.sun.enterprise.security.jacc.provider.SimplePolicyConfigurationFactory" policy-provider="com.sun.enterprise.security.jacc.provider.SimplePolicyProvider" name="simple" /> <audit-module classname="com.sun.enterprise.security.ee.Audit" name="default"> <property value="false" name="auditOn" /> </audit-module> <message-security-config auth-layer="SOAP"> <provider-config provider-id="XWS_ClientProvider" class-name="com.sun.xml.wss.provider.ClientSecurityAuthModule" provider-type="client"> <request-policy auth-source="content" /> <response-policy auth-source="content" /> <property value="s1as" name="encryption.key.alias" /> <property value="s1as" name="signature.key.alias" /> <property value="false" name="dynamic.username.password" /> <property value="false" name="debug" /> </provider-config> <provider-config provider-id="ClientProvider" class-name="com.sun.xml.wss.provider.ClientSecurityAuthModule" provider-type="client"> <request-policy auth-source="content" /> <response-policy auth-source="content" /> <property value="s1as" name="encryption.key.alias" /> <property value="s1as" name="signature.key.alias" /> <property value="false" name="dynamic.username.password" /> <property value="false" name="debug" /> <property value="${com.sun.aas.instanceRoot}/config/wss-server-config-1.0.xml" name="security.config" /> </provider-config> <provider-config provider-id="XWS_ServerProvider" class-name="com.sun.xml.wss.provider.ServerSecurityAuthModule" provider-type="server"> <request-policy auth-source="content" /> <response-policy auth-source="content" /> <property value="s1as" name="encryption.key.alias" /> <property value="s1as" name="signature.key.alias" /> <property value="false" name="debug" /> </provider-config> <provider-config provider-id="ServerProvider" class-name="com.sun.xml.wss.provider.ServerSecurityAuthModule" provider-type="server"> <request-policy auth-source="content" /> <response-policy auth-source="content" /> <property value="s1as" name="encryption.key.alias" /> <property value="s1as" name="signature.key.alias" /> <property value="false" name="debug" /> <property value="${com.sun.aas.instanceRoot}/config/wss-server-config-1.0.xml" name="security.config" /> </provider-config> </message-security-config> <property value="SHA-256" name="default-digest-algorithm" /> </security-service> <transaction-service tx-log-dir="${com.sun.aas.instanceRoot}/logs" > </transaction-service> <hazelcast-runtime-configuration enabled="false" multicastGroup="224.2.2.4" multicastPort="2904" generate-names="true"></hazelcast-runtime-configuration> <phone-home-runtime-configuration></phone-home-runtime-configuration> <request-tracing-service-configuration> <log-notifier enabled="true"></log-notifier> </request-tracing-service-configuration> <notification-service-configuration enabled="true"> <log-notifier-configuration enabled="true"></log-notifier-configuration> <eventbus-notifier-configuration enabled="false"></eventbus-notifier-configuration> </notification-service-configuration> <batch-runtime-configuration table-prefix="jbatch" data-source-lookup-name="jdbc/__default"></batch-runtime-configuration> <availability-service availability-enabled="true" > <web-container-availability availability-enabled="true" persistence-scope="modified-session" sso-failover-enabled="true" persistence-type="hazelcast"></web-container-availability> <!--<ejb-container-availability sfsb-ha-persistence-type="hazelcast" sfsb-persistence-type="hazelcast" ></ejb-container-availability>--> </availability-service> <network-config> <protocols> <protocol name="http-listener"> <http default-virtual-server="server" xpowered-by="false" max-connections="250" comet-support-enabled="true"> <file-cache enabled="false"></file-cache> </http> </protocol> <protocol security-enabled="true" name="https-listener"> <http default-virtual-server="server" xpowered-by="false" comet-support-enabled="true" max-connections="250"> <file-cache enabled="false"></file-cache> </http> <ssl classname="com.sun.enterprise.security.ssl.GlassfishSSLImpl" ssl3-enabled="false" cert-nickname="s1as"></ssl> </protocol> </protocols> <network-listeners> <network-listener port="8080" protocol="http-listener" transport="tcp" name="http-listener" thread-pool="http-thread-pool" enabled="true" /> <network-listener port="8443" protocol="https-listener" transport="tcp" name="https-listener" thread-pool="http-thread-pool" enabled="false" /> </network-listeners> <transports> <transport byte-buffer-type="HEAP" name="tcp" acceptor-threads="-1"></transport> </transports> </network-config> <thread-pools> <thread-pool name="http-thread-pool" min-thread-pool-size="10" max-thread-pool-size="200" max-queue-size="4096"></thread-pool> <thread-pool name="thread-pool-1" min-thread-pool-size="2" max-thread-pool-size="200"/> </thread-pools> </config> </configs> <system-property name="fish.payara.classloading.delegate" value="false"/> <property name="administrative.domain.name" value="domain1"/> </domain> 

سأعطيك أيضًا مثالاً على ملف وصف المورد لإنشاءها تلقائيًا في بداية التطبيق.


fishfish-resources.xml
 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd"> <resources> <jdbc-resource enabled="true" jndi-name="java:app/ora_con" object-type="user" pool-name="java:app/OraPool"/> <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="table" driver-classname="com.p6spy.engine.spy.P6SpyDriver" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="true" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="java:app/OraPool" non-transactional-connections="false" ping="false" pool-resize-quantity="2" pooling="true" res-type="java.sql.Driver" statement-cache-size="0" statement-leak-reclaim="false" statement-leak-timeout-in-seconds="0" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" validation-table-name="DUAL" wrap-jdbc-objects="true"> <property name="URL" value="${db.ora.url}"/> <property name="User" value="system"/> <property name="Password" value="1"/> <property name="property.dynamic-reconfiguration-waittimeout-in-seconds" value="60" /> </jdbc-connection-pool> <jdbc-resource enabled="true" jndi-name="java:app/pg_con" object-type="user" pool-name="java:app/PGPool"/> <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="table" driver-classname="com.p6spy.engine.spy.P6SpyDriver" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="true" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="java:app/PGPool" non-transactional-connections="false" ping="false" pool-resize-quantity="2" pooling="true" res-type="java.sql.Driver" statement-cache-size="0" statement-leak-reclaim="false" statement-leak-timeout-in-seconds="0" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" validation-table-name="DUAL" wrap-jdbc-objects="true"> <property name="URL" value="${db.pg.url}"/> <property name="User" value="postgres"/> <property name="Password" value="postgres"/> <property name="property.dynamic-reconfiguration-waittimeout-in-seconds" value="60" /> </jdbc-connection-pool> </resources> 

يمكنك تثبيت dcevm من هنا . تأكد من تثبيته كملف JVM بديل بحيث يكون لديك دائمًا فرصة للعمل على إعداد افتراضي منتظم.


يمكنك تنزيل أحدث إصدار من الوكيل لتعديل رمز مصدر غير محدود ، بالإضافة إلى إعادة تحميل التعليمات البرمجية داخل أطر مثل الإسبات من هنا .


جاءت أفكار إعداد إعادة تحميل الرمز لـ payara من هنا . لكن الحقيقة ليست سوى الفكرة نفسها ، حيث أن تطبيق payara-micro لا يعتبر هناك.


بفضل مكتبة p6spy ، يمكنك العثور على سجلات SQL الخاصة بك في مجلد جذر المشروع - ملف spy.log. يمكن تخصيص مكتبة p6spy إذا لزم الأمر ، ولكن هذا موضوع مقال مختلف تمامًا.


بعد وضع ملف التعريف الموضح أعلاه في pom.xml والملفات الإضافية التي نوقشت أعلاه في المجلدات المناسبة ، يمكنك بدء التطبيق الخاص بك باستخدام الأمر التالي:


 mvn install exec:exec -P micro 

ولا توجد ملحقات إضافية لخادم التطبيق في IDE مطلوبة ...

Source: https://habr.com/ru/post/ar422061/


All Articles