Kata pengantar
Ketika kami menggunakan anotasi @Discoveryclient, apakah kami akan memiliki pertanyaan berikut: Mengapa ia melakukan operasi mendaftarkan layanan? Bukankah seharusnya digunakan sebagai penemuan layanan? Mari kita jelajahi kode sumbernya secara mendalam.
1. Antarmuka Siklus Hidup Springframework
Untuk memahami masalah ini, kita perlu memahami antarmuka penting ini:
/ * * Hak Cipta 2002-2015 Penulis atau penulis asli. * * Dilisensikan di bawah lisensi Apache, versi 2.0 ("lisensi"); * Anda tidak boleh menggunakan file ini kecuali sesuai dengan lisensi. * Anda dapat memperoleh salinan lisensi di * * http://www.apache.org/licenses/license-2.0 * * kecuali diharuskan oleh hukum yang berlaku atau disepakati secara tertulis, perangkat lunak * yang didistribusikan di bawah lisensi didistribusikan atas dasar "sebagaimana adanya", * tanpa jaminan atau ketentuan apa pun, baik yang diungkapkan atau disiratkan. * Lihat lisensi untuk izin yang mengatur bahasa tertentu dan * batasan di bawah lisensi. */paket org.springframework.context;/*** Metode yang menentukan antarmuka umum untuk kontrol siklus hidup start/stop. * Kasus penggunaan yang khas untuk ini adalah untuk mengontrol pemrosesan asinkron. * <b> Catatan: Antarmuka ini tidak menyiratkan semantik startup otomatis tertentu. * Pertimbangkan menerapkan {@link SmartLifeCycle} untuk tujuan itu. </b> * * <p> Dapat diimplementasikan oleh kedua komponen (biasanya kacang pegas yang didefinisikan dalam konteks * pegas) dan kontainer (biasanya pegas {@link applicationContext} * sendiri). Wadah akan menyebarkan sinyal start/stop untuk semua komponen yang * berlaku di dalam setiap wadah, misalnya untuk skenario berhenti/restart saat runtime. * * <p> Dapat digunakan untuk doa langsung atau untuk operasi manajemen melalui JMX. * Dalam kasus terakhir, {@link org.springframework.jmx.export.mbeanExporter} * biasanya akan didefinisikan dengan * {@link org.springframework.jmx.export.assembler. * * <p> Perhatikan bahwa antarmuka siklus hidup hanya didukung pada <b> Singleton * Beans tingkat atas </b>. Pada komponen lainnya, antarmuka siklus hidup akan tetap tidak terdeteksi * dan karenanya diabaikan. Juga, perhatikan bahwa antarmuka {@link smartlifecycle} yang diperluas * memberikan integrasi dengan fase startup dan shutdown konteks aplikasi. * * @author juergen hoeller * @since 2.0 * @see smartlifecycle * @see configurableApplicationContext * @see org.springframework.jms.springframework.scheduling.scheduling * @see org.springframework.scheduling * @see org.springframework.scheduling.scheduling * @see org.springframework.scheduling { /*** Mulai komponen ini. * <p> Tidak boleh melempar pengecualian jika komponen sudah berjalan. * <p> Dalam kasus wadah, ini akan menyebarkan sinyal start ke semua * komponen yang berlaku. * @see SmartLifeCycle#isAutostArtup () */ void start (); /** * Hentikan komponen ini, biasanya secara sinkron, sehingga komponennya * sepenuhnya dihentikan setelah kembali dari metode ini. Pertimbangkan mengimplementasikan {@link SmartLifeCycle} * dan varian {@code stop (runnable)} ketika perilaku berhenti asinkron diperlukan. * <p> Perhatikan bahwa pemberitahuan berhenti ini tidak dijamin akan datang sebelum kehancuran: pada * shutdown reguler, {@code lifecycle} kacang pertama akan menerima pemberitahuan berhenti sebelum * Callback penghancuran umum sedang diperbanyak; Namun, pada penyegaran panas selama kehidupan * konteks atau pada upaya penyegaran yang dibatalkan, hanya metode menghancurkan yang akan dipanggil. * <p> Tidak boleh melempar pengecualian jika komponen belum dimulai. * <p> Dalam kasus wadah, ini akan menyebarkan sinyal berhenti ke semua komponen * yang berlaku. * @see SmartLifeCycle#stop (runnable) * @see org.springframework.beans.factory.disposablean#hancurkan () */ void stop (); /*** Periksa apakah komponen ini sedang berjalan. * <p> Dalam kasus wadah, ini akan mengembalikan {@code true} hanya jika <i> semua </i> * komponen yang berlaku saat ini sedang berjalan. * @return apakah komponen sedang berjalan */ boolean isrunning ();}Antarmuka ini mendefinisikan metode kontrol siklus hidup start/stop. Ketika wadah IOC pegas dimulai atau berhenti, sinyal awal atau berhenti akan dikirim ke setiap komponen, sehingga kita dapat melakukan apa yang kita inginkan dalam metode yang sesuai. Kita dapat menemukan melalui diagram kelas bahwa kita biasanya menggunakan kelas ClassPathXMLapPlicationContext mengimplementasikan antarmuka ini
Mari kita tunjukkan secara singkat kasus ini dan buat kelas mylifecycle:
Paket org.hzgj.spring.study.context; impor org.springframework.context.smartlifecycle; kelas publik mylifecycle mengimplementasikan smartlifecycle {@override public start () {system.println ("mylifecycle start ...."); } @Override public void stop () {System.out.println ("MyLifeCycle Stop ....."); } @Override public boolean isRunning () {return false; } @Override public boolean isAutostArtup () {return true; } @Override public void stop (runnable callback) {} @Override public int getPhase () {System.out.println ("fase"); kembali 10; }}Di sini kami mewarisi siklus pintar. Antarmuka mewarisi siklus hidup. Metode isrunning digunakan untuk mendeteksi apakah komponen saat ini dalam keadaan berjalan. Perhatikan bahwa itu hanya dapat berjalan ketika nilai pengembalian adalah false.
Kami mengkonfigurasi mylifecycle ke dalam file konfigurasi pegas, dan menjalankan melalui classpathxmlapplicationContext untuk mendapatkan hasil berikut:
Selain itu, metode getPhase di sini adalah untuk menentukan nilai tahap (dapat dipahami sebagai prioritas. Semakin kecil nilainya, semakin banyak siklus hidup yang sesuai dieksekusi terlebih dahulu)
2. Penelitian Kode Sumber Discoveryclient
@EnableDiscoveyClient
/ * * Hak Cipta 2013-2015 Penulis atau penulis asli. * * Dilisensikan di bawah lisensi Apache, versi 2.0 ("lisensi"); * Anda tidak boleh menggunakan file ini kecuali sesuai dengan lisensi. * Anda dapat memperoleh salinan lisensi di * * http://www.apache.org/licenses/license-2.0 * * kecuali diharuskan oleh hukum yang berlaku atau disepakati secara tertulis, perangkat lunak * yang didistribusikan di bawah lisensi didistribusikan atas dasar "sebagaimana adanya", * tanpa jaminan atau ketentuan apa pun, baik yang diungkapkan atau disiratkan. * Lihat lisensi untuk izin tata kelola bahasa tertentu dan * batasan di bawah lisensi. */paket org.springframework.cloud.client.discovery; impor java.lang.annotation.dokumen; impor java.lang.annotation.elementType; impor java.lang.annotation.herherited; impor java.lang.annotation.Rretensi; impor java.Lang. java.lang.annotation.target; impor org.springframework.context.annotation.import;/*** anotasi untuk memungkinkan implementasi penemuan. * @Author Spencer Gibb * /@target (elementType.type) @retention (retentionpolicy.runtime)@didokumentasikan@warisan@impor (enableDiscoveryclientImportSelector.class) public @Interface enableDiscoverClient { /** jika benar, serviceregistry akan mendaftarkan The Otomatis secara otomatis. */ boolean autoregister () default true;} Harap dicatat bahwa @Import(EnableDiscoveryClientImportSelector.class) kami dapat merujuk ke kelas ini:
/ * * Hak Cipta 2013-2015 Penulis atau penulis asli. * * Dilisensikan di bawah lisensi Apache, versi 2.0 ("lisensi"); * Anda tidak boleh menggunakan file ini kecuali sesuai dengan lisensi. * Anda dapat memperoleh salinan lisensi di * * http://www.apache.org/licenses/license-2.0 * * kecuali diharuskan oleh hukum yang berlaku atau disepakati secara tertulis, perangkat lunak * yang didistribusikan di bawah lisensi didistribusikan atas dasar "sebagaimana adanya", * tanpa jaminan atau ketentuan apa pun, baik yang diungkapkan atau disiratkan. * Lihat lisensi untuk izin yang mengatur bahasa tertentu dan * batasan di bawah lisensi. */Paket org.springframework.cloud.client.discovery; impor org.springframework.boot.bind.relaxedpropertyryolver; impor org.springframework.cloud.commons.util.springoryMportSelector; impor org.cramram.commons.util.springoryporportselector; import org.spramram.cpramram.core.core.core.springory org.springframework.core.annotation.AnnotationAttributes; impor org.springframework.core.annotation.order; impor org.springframework.core.env.configableArvironment; impor org.springframework.core.env.envonment; org.springframework.core.env.mappropertysource; impor org.springframework.core.type.annotationmetadata; impor java.util.arraylist; impor java.util.arrays; Impor Java.util.linkedhashmaap; */ @Order (ordered.lowest_precedence - 100) kelas publik enableDiscoveryClientImportSelector memperluas springFactoryImportSelector <EnableDiscoveryClient> {@Override public string [] selectImports (annotationmetadata metadata) {string [] impor = super. Atribut AnnotationAttributes = AnnotationAttributes.frommap (metadata.getAnnotationAttributes (getAnnotationClass (). GetName (), true))); boolean autoregister = attributes.getBoolean ("autoregister"); if (autoregister) {list <string> importSlist = new arraylist <> (arrays.aslist (impor)); importslist.add ("org.springframework.cloud.client.serviceregistry.AutoServiceregistrationConfiguration"); impor = imporSlist.toArray (string baru [0]); } else {lingkungan env = getEnvironment (); if (configAbleNvironment.class.isInstance (env)) {configAbleNvironment configEnv = (ConfigAbleNeNvironment) Env; LinkedHashMap <String, Object> Map = new LinkedHashMap <> (); peta.put ("spring.cloud.service-registry.auto-registration.enabled", false); Mappropertysource propertysource = mappropertysource baru ("springclouddiscoveryclient", peta); configenv.getPropertySources (). AddLast (PropertiesSource); }} pengembalian impor; } @Override dilindungi boolean isenabled () {return new relaxedPropertyRyolver (getenvironment ()). GetProperty ("spring.cloud.discovery.enabled", boolean.class, boolean.true); } @Override Protected Boolean HasDefaultFactory () {return true; }} Metode penulisan ulang kelas ini berasal dari antarmuka importSelector. Kami dapat melacak kelas sesuai dengan kode di bawah if(autoRegister) : org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration . Mari kita lihat diagram struktural:
Kita dapat mengetahui bahwa kelas ini mengimplementasikan antarmuka siklus hidup, jadi mari kita lihat metode awal, yang ada di kelas induknya AbstractDiscoverylifecycle:
/ * * Hak Cipta 2013-2015 Penulis atau penulis asli. * * Dilisensikan di bawah lisensi Apache, versi 2.0 ("lisensi"); * Anda tidak boleh menggunakan file ini kecuali sesuai dengan lisensi. * Anda dapat memperoleh salinan lisensi di * * http://www.apache.org/licenses/license-2.0 * * kecuali diharuskan oleh hukum yang berlaku atau disepakati secara tertulis, perangkat lunak * yang didistribusikan di bawah lisensi didistribusikan atas dasar "sebagaimana adanya", * tanpa jaminan atau ketentuan apa pun, baik yang diungkapkan atau disiratkan. * Lihat lisensi untuk izin yang mengatur bahasa tertentu dan * batasan di bawah lisensi. */paket org.springframework.cloud.client.discovery; import java.util.concurrent.atomic.atomicboolean; import java.util.concurrent.atomic.atomicinteger; import javax.annotation.predestroy; import org.apache.common.common. org.apache.commons.logging.LogFactory;import org.springframework.beans.BeansException;import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;import org.springframework.cloud.client.serviceregistry.serviceregistry; impor org.springframework.context.applicationContext; impor org.springframework.context.applicationContextAware; org.springframework.context org.springframework.core.env.environment;/*** Metode siklus hidup yang mungkin berguna dan umum untuk berbagai implementasi penemuan. * * @deprecated menggunakan {@link org.springframework.cloud.client.serviceregistry.AbstractAutoServiceregistration} sebagai gantinya. Kelas ini akan dihapus di kereta rilis berikutnya. * * @author spencer gibb */ @decrecatedpublic abstract class abstractDiscoverylifecycle mengimplementasikan DiscoveryLifecycle, ApplicationContextAware, ApplicationListener <embeddedServletContainerInitializedEvent> {private static logger = logfactory.getLogylog (abstraccovercovercleif.ckleif); private boolean autostartup = true; Private Atomicboolean Running = atomicboolean baru (false); private int order = 0; konteks private applicationContext; lingkungan lingkungan pribadi; port atomicinteger pribadi = atomicinteger baru (0); Protected ApplicationContext getContext () {return Context; } @Override public void setApplicationContext (ApplicationContext ApplicationContext) melempar BeansException {this.context = ApplicationContext; this.environment = this.context.getEnvironment (); } @Deprecated Environment Getenvironment () {Return Environment; } @Deprecated atomicinteger getport () {port return; } @Override public boolean isAutostArtup () {return this.autostartup; } @Override public void stop (runnable callback) {coba {stop (); } catch (Exception e) {logger.error ("Masalah terjadi mencoba menghentikan siklus hidup penemuan", e); } callback.run (); } @Override public void start () {if (! IsEnabled ()) {if (logger.isdebugeNabled ()) {Logger.debug ("Discabled Lifecycle Disabled. Tidak Memulai"); } kembali; } // Hanya atur port jika nonsecureport adalah 0 dan this.port! = 0 if (this.port.get ()! = 0 && getConfiguredport () == 0) {setConfiguredport (this.port.get ()); } // Hanya inisialisasi jika nonsecureport lebih besar dari 0 dan belum berjalan // karena containerportInitializer di bawah ini jika (! this.running.get () && getConfiguredport ()> 0) {register (); if (harus registermanagement ()) {registerManagement (); } this.context.publishevent (InstanceregisteredEvent baru <> (ini, getConfiguration ())); this.running.comppareandset (false, true); }} @Deprecated abstrak yang dilindungi int getConfiguredport (); @Deprecated abstrak void setConfiguredport (int port); / ** * @Return Jika layanan manajemen harus terdaftar dengan {@link serviceregistry} */ boolean yang dilindungi harus registermanagement () {return getManagementport ()! = null && managementserverportutils.isdifferent (this.context); } / ** * @return Objek yang digunakan untuk mengonfigurasi pendaftaran * / @Deprecated objek abstrak yang dilindungi getConfiguration (); / ** * Daftarkan Layanan Lokal dengan DiscoveryClient */ Protected Abstract Void Register (); / ** * Daftarkan Layanan Manajemen Lokal dengan DiscoveryClient */ Protected Void RegisterManagement () {}/ ** * de-register layanan lokal dengan DiscoveryClient */ protected abstrak void Deregister (); / ** * de-register Layanan manajemen lokal dengan DiscoveryClient */ void DeregisterManagement () {}/ ** * @return true, jika {@link DiscoveryLifecycle} diaktifkan */ abstrak yang dilindungi boolean terenakled (); / ** * @return LayananID dari Layanan Manajemen */ @Deprecated string yang dilindungi getManagementserviceId () {// TODO: Suffix manajemen yang dapat dikonfigurasi mengembalikan this.context.getId () + ": manajemen"; } / ** * @return Nama layanan dari Layanan Manajemen * / @Deprecated string yang dilindungi getManagementserviceName () {// TODO: Sufiks manajemen yang dapat dikonfigurasi kembali getAppname () + ": manajemen"; } / ** * @return port server manajemen * / @Deprecated integer getManagementport () {return managementserverportutils.getport (this.context); } / ** * @return Nama aplikasi, saat ini properti spring.application.name * / @Deprecated string yang dilindungi getAppname () {return this.environment.getProperty ("spring.application.name", "Application"); } @Override public void stop () {if (this.running.compareandset (true, false) && isEnabled ()) {Deregister (); if (harus registermanagement ()) {DeregisterManagement (); }}} @Predestroy public void dashing () {stop (); } @Override public boolean isRunning () {return this.running.get (); } atomicboolean getRunning () {return running; } @Override public int getorder () {return this.order; } @Override public int getPhase () {return 0; } @Override @Deprecated public void onApplicationEvent (embeddedServletContainerInitializedEvent peristiwa) {// todo: memperhitungkan ssl ke akun // jangan mendaftarkan port manajemen sebagai port jika (! "Manajemen" .Equals (event.getApplicationContext (). GetNamespace ())) () (Event.getApplicationContext (). GetNamespace ())) ()) (Event.getApplicationContext (). GetNamespace ())) {) {) {event. event.getembeddedServletContainer (). getport ()); this.start (); }}}Perhatikan bahwa ada sepotong kode ini dalam metode start:
if (! this.running.get () && getConfiguredport ()> 0) {register (); if (harus registermanagement ()) {registerManagement (); } this.context.publishevent (InstanceregisteredEvent baru <> (ini, getConfiguration ())); this.running.comppareandset (false, true); } Harap dicatat register() adalah metode abstrak di kelas ini. Jadi mari kita lihat kembali kode di kelas abstractAutoServiceregistration, dan saya hanya akan memposting bagian -bagian utama di sini:
// ..... dilindungi abstractAutoServiceregistration (serviceregistry <r> Serviceregistry, AutoserviceregistrationProperties Properties) {this.serviceregistry = serviceregistry; this.properties = properti; } //....../** * Daftarkan Layanan Lokal dengan {@link ServiceRegistry} */@Override Protected Void Register () {this.serviceregistry.register (getRegistration ()); }Kita dapat menemukan bahwa tipe serviceregistry dilewatkan dalam konstruktor, yang merupakan antarmuka Springcloud memberi kami untuk pendaftaran layanan. Di sini eurekaserviceregistry mengimplementasikan antarmuka ini:
/ * * Hak Cipta 2013-2016 Penulis asli atau penulis. * * Dilisensikan di bawah lisensi Apache, versi 2.0 ("lisensi"); * Anda tidak boleh menggunakan file ini kecuali sesuai dengan lisensi. * Anda dapat memperoleh salinan lisensi di * * http://www.apache.org/licenses/license-2.0 * * kecuali diharuskan oleh hukum yang berlaku atau disepakati secara tertulis, perangkat lunak * yang didistribusikan di bawah lisensi didistribusikan atas dasar "sebagaimana adanya", * tanpa jaminan atau ketentuan apa pun, baik yang diungkapkan atau disiratkan. * Lihat lisensi untuk izin yang mengatur bahasa tertentu dan * batasan di bawah lisensi. * */paket org.springframework.cloud.netflix.eureka.serviceregistry; impor java.util.hashmap; impor org.apache.commons.logging.log; impor org.apache.commons.logging.logfactory; impor org.springfringfring. com.netflix.appinfo.instanceInfo;/** * @author spencer gibb */kelas publik eurekaserviceregistry mengimplementasikan serviceregistry <eurekaregistration> {log private static log = logfactory.getLog (eurekaserviceregy.class); @Override public void register (eurekaregistration reg) {mungkininitializeClient (reg); if (log.isInfoeNabled ()) {log.info ("Aplikasi Mendaftar" + Reg.GetInstanceConfig (). GetAppname () + "dengan eureka dengan status" + reg.getInstanceconfig (). getInitialstatus ()); } Reg.getAppLicationInfomanager () .setInstanceStatus (Reg.getInstanceConfig (). getInitialStatus ()); if (reg.gethealthcheckHandler ()! = null) {reg.geteureKaClient (). RegisterHealthCheck (Reg.GetHealthCeckHandler ()); }} private void MaybeInitializeClient (eurekaregistration reg) {// memaksa inisialisasi proxies yang mungkin dilingkupkan Reg.getApplicationInfomanager (). getInfo (); reg.geteureKaclient (). getApplications (); } @Override public void Deregister (eurekaregistration reg) {if (reg.getApplicationInfomanager (). GetInfo ()! = Null) {if (log.isInfoEnabled ()) {log.info ("tidak terdaftar aplikasi" + reg.getinstancececececececcecceccecccangg () (). } Reg.getAppLicationInfomanager (). SetInstanceStatus (instanceInfo.instancestatus.down); // Shutdown dari klien Eureka harus terjadi dengan eurekaregistration.close () // pendaftaran otomatis akan membuat kacang yang akan didistribusikan dengan benar // pendaftaran manual perlu memanggil tutup ()}} @Override public setstatus (eureKaregistration Registration, status string) {instanceinfoInfo. // TODO: Bagaimana menangani hapus dengan benar? if ("cancel_override" .equalsignorecase (status)) {registration.geteureKaclient (). cancelOverridestatus (info); kembali; } // TODO: Bagaimana menangani jenis status di seluruh sistem penemuan? InstanceInfo.instancestatus newstatus = instanceInfo.instancestatus.toenum (status); registrasi.geteureKaclient (). setstatus (newstatus, info); } @Override Objek publik getStatus (registrasi eurekaregistrasi) {hashMap <string, object> status = hashmap baru <> (); InstanceInfo info = Registration.getApplicationInfomanager (). GetInfo (); status.put ("status", info.getStatus (). ToString ()); status.put ("overridedstatus", info.getoverriddidstatus (). tostring ()); status pengembalian; } public void close () {}}Jadi kita dapat meringkas poin -poin berikut:
1. Menggunakan @Discoveryclient untuk mendaftarkan Layanan menggunakan mekanisme siklus hidup, dan metode register() serviceregistry akan dieksekusi ketika wadah dimulai.
2. Menggunakan @Discoveryclient lebih fleksibel daripada @EnableEureKaclient dan @EnableEureKaserver, karena memblokir implementasi pendaftaran layanan, dan kami bahkan dapat menyesuaikan pusat pendaftaran.
3. Ini juga akan secara otomatis mencari implementasi antarmuka penemuan untuk penemuan layanan.
3. Pusat Pendaftaran Redis Praktis DiscoveryClient
Di bawah ini kami menerapkan persyaratan berdasarkan Redis sebagai pusat pendaftaran untuk memahami penemuan. Ngomong -ngomong, mari kita pahami antarmuka penting dari Springcloud: Serviceregistry, ServiceInstance. Sebelum ini, kami akan menambahkan dukungan untuk Redis:
Group kompilasi: 'org.springframework.boot', nama: 'Spring-boot-starter-data-redis'
1. Menerapkan antarmuka pendaftaran
Paket com.hzgj.lyrk.member; impor org.springframework.beans.factory.annotation.value; impor org.springframework.cloud.client.serviceregistry. java.net.uri; import java.util.enumeration; import java.util.map; @ComponentPublic kelas redisregistrasi mengimplementasikan pendaftaran {@value ("$ {server.port}") port integer pribadi; @Value ("$ {spring.application.name}") Private String ApplicationName; host string pribadi; public void setHost (string host) {this.host = host; } public void setport (port integer) {this.port = port; } public void setApplicationName (String ApplicationName) {this.applicationName = ApplicationName; } @Override Public String getServiceId () {return applicationName + ":" + getHost () + ":" + getport (); } @Override Public String getHost () {coba {if (host == null) return getLocalHostLanAddress (). GetHostAddress (); lain mengembalikan host; } catch (Exception e) {E.PrintStackTrace (); } return null; } @Override public int getport () {return port; } @Override public boolean issecure () {return false; } @Override public uri geturi () {return null; } @Override peta publik <string, string> getMetadata () {return null; } public string getServiceName () {return this.applicationName; } public inetaddress getLocalHostLanAddress () melempar Exception {coba {inetaddress candidateAddress = null; // Traverse semua antarmuka jaringan untuk (enumeration ifaces = networkInterface.getNetworkInterfaces (); ifaces.hasmoreElements ();) {networkInterface iface = (networkInterface) ifaces.nextElement (); // Lintasi IP di bawah semua antarmuka untuk (enumeration inetaddrs = iface.getInetaddresses (); inetaddrs.hasmoreElements ();) {inetaddress inetaddr = (inetaddress) inetaddrs.nextelement (); if (! inetaddr.isloopbackAddress ()) {// Kecualikan alamat jenis loopback if (inetaddr.issitelocalAddress ()) {// Jika itu adalah alamat lokasi-lokal, itu dikembalikan inetaddr; } lain if (candidateAddress == null) {// Alamat jenis situs-lokal belum ditemukan, pertama rekam kandidat alamat candidateaddress = inetaddr; }}}}} if (candidateAddress! = null) {return candidateAddress; } // Jika tidak ada alamat non-loopback yang ditemukan, Anda hanya dapat menggunakan solusi yang paling dipilih. Inetaddress JDKSuppliedAddress = inetaddress.getLocalhost (); return JDKSuppliedAddress; } catch (Exception e) {E.PrintStackTrace (); } return null; }}Antarmuka ini mewarisi layanan Layanan, sehingga fungsi utama antarmuka ini adalah untuk menentukan spesifikasi instance layanan, seperti apa layanannya, berapa nomor port, dll.
2. Menerapkan antarmuka serviceregistry
Paket com.hzgj.lyrk.member; impor org.springframework.beans.factory.annotation.Autowired; impor org.springframework.cloud.client.serviceregistry. ServiceRegistry <RedisRegistration> {@Autowired Private StrreDistemplate redistemplate; @Override public void Register (RedisRegistration Registration) {String serviceId = Registration.getServiceId (); redistemplate.opsforlist (). Leftpush (serviceId, Registration.getHost () + ":" + Registration.getport ()); } @Override public void Deregister (pendaftaran redisregistrasi) {redistemplate.opsforlist (). Hapus (registrasi.getServiceId (), 1, registrasi.gethost () + ":" + registrasi.getport ()); } @Override public void close () {//redistemplate.d system.out.println ("Tutup ..."); } @Override public void setStatus (pendaftaran redisregistrasi, status string) {} @Override public <t> t getstatus (pendaftaran redisregistrasi) {return null; }}Fungsi utama antarmuka ini adalah untuk menentukan cara mendaftar, membatalkan layanan, mengatur dan mendapatkan status layanan, dll.
3. Warisan AbstractAutoserviceregistration Abstract Class
paket com.hzgj.lyrk.member; import org.springframework.beans.factory.annotation.Autowired; impor org.spramework.cloud.client.serviceregistry.cloRegracTerServicerEgistrasi; Impor org.springframework.cloud.cloud.cload.cloRiRITERIRIRERITER. org.springframework.cloud.client.serviceregistry.serviceregistry; kelas publik redisAutoserviceregistration memperluas abstrak -abstrak servisergasi <Redisregistrasi> {@Autowired pribadi redisregistrasi ulang; RedisAutoServiceregistration yang dilindungi (Serviceregistry <Redisregistration> Serviceeregistry, AutoserviceregistrationProperties Properties) {super (serviceregistry, properties); // serviceeregistry.register (getRegistration ()); } @Override intrected int getConfiguredport () {return redisregistration.getPort (); } @Override Protected void setConfiguredport (int port) {} @Override Objek Dilindungi GetConfiguration () {return null; } @Override dilindungi boolean isenabled () {return true; } @Override Protected Redisregistration getRegistration () {return redisregistration; } @Override Protected Redisregistration GetManagementRegistration () {return null; }}4. Tentukan kelas implementasi redisdiscoveryclient penemuan
package com.hzgj.lyrk.member;import org.apache.commons.lang.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cloud.client.ServiceInstance;import org.springframework.cloud.client.discovery.DiscoveryClient;import org.springframework.data.redis.core.stringredistemplate; impor java.util.arraylist; impor java.util.list; java.util.function. @Override Public String Description () {return "Discovery di Redis Registration Center"; } @Override Public ServiceInstance getLocalServiceInstance () {return null; } @Override Daftar Publik <ServiceInstance> getInstances (String serviceId) {return redistemplate.opsforlist (). Range (serviceId, 0, -1). ParallelStream (). MAP ((Function <String, ServiceInstance>) s -> {redisregistration redisregistration = redisregistration baru (); redisregistration.setApplicationName (serviceId); string hostName = stringutils.split (s, ":") [0]; string port = stringUntName = stringutils.split (s, ":") [0]; string port = stringUntName = Stringutils.split (s, ":") [0]; String port = StringUntName = Stringutils.split (s, ":") [0]; string port = stringutil. redisregistration.sethost (nama host); } @Override Public List <String> getServices () {list <string> list = new ArrayList <> (); list.addall (redistemplate.keys ("*")); daftar pengembalian; }}Kelas ini terutama ditujukan untuk penemuan layanan Pusat Pendaftaran Redis
5. Tentukan kelas perakitan otomatis untuk membuat kacang yang sesuai
Paket com.hzgj.lyrk.member; impor org.springframework.boot.autoconfigure.condition.conditionAlonproperty; impor org.springframework.boot.context.properties.enableConfigurationProperties; impor org.springframework.cloud.client.serviceregistry.AutoServiceregistrationProperties; impor org.springframework.context.annotation.bean; impor org.springframework.context.annotation.onfigurasi; Impor org.springframework.context.annotation.Primary;@Configuration@EnableConfigurationProperties(RedisConfig.class)@ConditionalOnProperty(value = "spring.redis.registry.enabled", matchIfMissing = true)public class RedisRegistryAutoConfiguration { @Bean RedisServiceRegistry RedisServiceregistry (Recisconfig Redisconfig) {System.out.println (RonaSconfig.GetHost ()); mengembalikan redisserviceregistry baru (); } @Bean RedisAutoServiceregistration RedisAutoServiceregistration (redisserviceregistry redisserviceregistry) {return redisautoserviceregistration baru (redisserviceregistry, AutoserviceregistrationProperties ()); } @Bean @primary redisdiscoveryclient redisdiscoveryclient () {return new redisDiscoveryclient (); }}6. Tentukan kelas startup
Paket com.hzgj.lyrk.member; impor org.springframework.boot.springapplication; impor org.springframework.boot.autoconfigure.springbootApplication; impor org.springframework.cloud.client.discovery.discoverycoveryclient; org.springframework.cloud.client.discovery.enableDiscoveryclient; impor org.springframework.cloud.client.discovery.springframework.cloud.client.clientcovery org.springframework.context.configurableApplicationContext;@enableDiscoveryclient@springbootApplication (exclude = {SimpleDiscoveryclientAutoconfiguration.class, compositedIscoveryclientAutocOnfiguration (classics}) {compositedIscoveryclionatic (classatic) {publicycoid {publicycoid {publicicy (classicing) {publicycoid {publicycoid {publicycoid {composityclication {publicicaticy {composityclication {composityclication {composityclication ConfigurableApplicationContext applicationContext = springApplication.run (magriclication.class, args); DiscoveryClient DiscoveryClient = ApplicationContext.getBean (DiscoveryClient.class); DiscoveryClient.GetServices (). Foreach (Action -> {System.out.println (Action);}); }}Di sini, perakitan default DiscoveryClient dikecualikan dalam anotasi springbootApplication.
Ketika kami berhasil memulai, kami dapat menemukan bahwa konsol memiliki output nama dan alamat layanan yang sesuai:
Kami sekali lagi menghasilkan file jar melalui kemasan lulusan dan menjalankan:
java -jar anggota-server-0.0.1-snapshot.jar --sver.port = 8800
Kita dapat melihat bahwa nilai terdaftar layanan yang telah di -cache di Redis:
Meringkaskan
Di atas adalah seluruh konten artikel ini. Saya berharap konten artikel ini memiliki nilai referensi tertentu untuk studi atau pekerjaan semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi. Terima kasih atas dukungan Anda ke wulin.com.