ಕಂಪೈಲ್ಡ್ ಡಿಸ್ಟ್ರಿಬ್ಯೂಟೆಡ್ ಸಿಸ್ಟಮ್ ಕಾನ್ಫಿಗರೇಶನ್

ವಿತರಿಸಿದ ಸಿಸ್ಟಮ್ನ ಸಂರಚನೆಯೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಲು ನಾನು ನಿಮಗೆ ಒಂದು ಆಸಕ್ತಿದಾಯಕ ಕಾರ್ಯವಿಧಾನವನ್ನು ಹೇಳಲು ಬಯಸುತ್ತೇನೆ. ಸಂರಚನೆಯನ್ನು ಸುರಕ್ಷಿತ ಪ್ರಕಾರಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಸಂಕಲಿಸಿದ ಭಾಷೆಯಲ್ಲಿ (ಸ್ಕಲಾ) ನೇರವಾಗಿ ಪ್ರತಿನಿಧಿಸಲಾಗುತ್ತದೆ. ಈ ಪೋಸ್ಟ್ ಅಂತಹ ಸಂರಚನೆಯ ಉದಾಹರಣೆಯನ್ನು ಒದಗಿಸುತ್ತದೆ ಮತ್ತು ಒಟ್ಟಾರೆ ಅಭಿವೃದ್ಧಿ ಪ್ರಕ್ರಿಯೆಯಲ್ಲಿ ಸಂಕಲಿಸಿದ ಸಂರಚನೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ವಿವಿಧ ಅಂಶಗಳನ್ನು ಚರ್ಚಿಸುತ್ತದೆ.

ಕಂಪೈಲ್ಡ್ ಡಿಸ್ಟ್ರಿಬ್ಯೂಟೆಡ್ ಸಿಸ್ಟಮ್ ಕಾನ್ಫಿಗರೇಶನ್

(ಇಂಗ್ಲೀಷ್)

ಪರಿಚಯ

ವಿಶ್ವಾಸಾರ್ಹ ವಿತರಣೆ ವ್ಯವಸ್ಥೆಯನ್ನು ನಿರ್ಮಿಸುವುದು ಎಂದರೆ ಎಲ್ಲಾ ನೋಡ್‌ಗಳು ಸರಿಯಾದ ಸಂರಚನೆಯನ್ನು ಬಳಸುತ್ತವೆ, ಇತರ ನೋಡ್‌ಗಳೊಂದಿಗೆ ಸಿಂಕ್ರೊನೈಸ್ ಮಾಡುತ್ತವೆ. DevOps ತಂತ್ರಜ್ಞಾನಗಳನ್ನು (ಟೆರಾಫಾರ್ಮ್, ಅನ್ಸಿಬಲ್ ಅಥವಾ ಅಂತಹದ್ದೇನಾದರೂ) ಸಾಮಾನ್ಯವಾಗಿ ಕಾನ್ಫಿಗರೇಶನ್ ಫೈಲ್‌ಗಳನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಉತ್ಪಾದಿಸಲು ಬಳಸಲಾಗುತ್ತದೆ (ಸಾಮಾನ್ಯವಾಗಿ ಪ್ರತಿ ನೋಡ್‌ಗೆ ನಿರ್ದಿಷ್ಟವಾಗಿದೆ). ಎಲ್ಲಾ ಸಂವಹನ ನೋಡ್‌ಗಳು ಒಂದೇ ರೀತಿಯ ಪ್ರೋಟೋಕಾಲ್‌ಗಳನ್ನು ಬಳಸುತ್ತಿವೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ನಾವು ಬಯಸುತ್ತೇವೆ (ಅದೇ ಆವೃತ್ತಿಯನ್ನು ಒಳಗೊಂಡಂತೆ). ಇಲ್ಲದಿದ್ದರೆ, ನಮ್ಮ ವಿತರಣಾ ವ್ಯವಸ್ಥೆಯಲ್ಲಿ ಅಸಾಮರಸ್ಯವನ್ನು ನಿರ್ಮಿಸಲಾಗುತ್ತದೆ. JVM ಜಗತ್ತಿನಲ್ಲಿ, ಈ ಅವಶ್ಯಕತೆಯ ಒಂದು ಪರಿಣಾಮವೆಂದರೆ ಪ್ರೋಟೋಕಾಲ್ ಸಂದೇಶಗಳನ್ನು ಹೊಂದಿರುವ ಲೈಬ್ರರಿಯ ಒಂದೇ ಆವೃತ್ತಿಯನ್ನು ಎಲ್ಲೆಡೆ ಬಳಸಬೇಕು.

ವಿತರಿಸಿದ ವ್ಯವಸ್ಥೆಯನ್ನು ಪರೀಕ್ಷಿಸುವ ಬಗ್ಗೆ ಏನು? ಸಹಜವಾಗಿ, ನಾವು ಏಕೀಕರಣ ಪರೀಕ್ಷೆಗೆ ತೆರಳುವ ಮೊದಲು ಎಲ್ಲಾ ಘಟಕಗಳು ಘಟಕ ಪರೀಕ್ಷೆಗಳನ್ನು ಹೊಂದಿವೆ ಎಂದು ನಾವು ಭಾವಿಸುತ್ತೇವೆ. (ರನ್‌ಟೈಮ್‌ಗೆ ಪರೀಕ್ಷಾ ಫಲಿತಾಂಶಗಳನ್ನು ಎಕ್ಸ್‌ಟ್ರಾಪೋಲೇಟ್ ಮಾಡಲು, ನಾವು ಪರೀಕ್ಷಾ ಹಂತದಲ್ಲಿ ಮತ್ತು ರನ್‌ಟೈಮ್‌ನಲ್ಲಿ ಒಂದೇ ರೀತಿಯ ಲೈಬ್ರರಿಗಳನ್ನು ಸಹ ಒದಗಿಸಬೇಕು.)

ಏಕೀಕರಣ ಪರೀಕ್ಷೆಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವಾಗ, ಎಲ್ಲಾ ನೋಡ್‌ಗಳಲ್ಲಿ ಎಲ್ಲೆಡೆ ಒಂದೇ ಕ್ಲಾಸ್‌ಪಾತ್ ಅನ್ನು ಬಳಸುವುದು ಸುಲಭವಾಗಿದೆ. ನಾವು ಮಾಡಬೇಕಾಗಿರುವುದು ಒಂದೇ ಕ್ಲಾಸ್‌ಪಾತ್ ಅನ್ನು ರನ್‌ಟೈಮ್‌ನಲ್ಲಿ ಬಳಸಲಾಗಿದೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳುವುದು. (ವಿಭಿನ್ನ ಕ್ಲಾಸ್‌ಪಾತ್‌ಗಳೊಂದಿಗೆ ವಿಭಿನ್ನ ನೋಡ್‌ಗಳನ್ನು ಚಲಾಯಿಸಲು ಇದು ಸಂಪೂರ್ಣವಾಗಿ ಸಾಧ್ಯವಾದರೂ, ಇದು ಒಟ್ಟಾರೆ ಕಾನ್ಫಿಗರೇಶನ್‌ಗೆ ಸಂಕೀರ್ಣತೆಯನ್ನು ಸೇರಿಸುತ್ತದೆ ಮತ್ತು ನಿಯೋಜನೆ ಮತ್ತು ಏಕೀಕರಣ ಪರೀಕ್ಷೆಗಳಲ್ಲಿನ ತೊಂದರೆಗಳನ್ನು ನೀಡುತ್ತದೆ.) ಈ ಪೋಸ್ಟ್‌ನ ಉದ್ದೇಶಗಳಿಗಾಗಿ, ಎಲ್ಲಾ ನೋಡ್‌ಗಳು ಒಂದೇ ಕ್ಲಾಸ್‌ಪಾತ್ ಅನ್ನು ಬಳಸುತ್ತವೆ ಎಂದು ನಾವು ಭಾವಿಸುತ್ತೇವೆ.

ಅಪ್ಲಿಕೇಶನ್‌ನೊಂದಿಗೆ ಕಾನ್ಫಿಗರೇಶನ್ ವಿಕಸನಗೊಳ್ಳುತ್ತದೆ. ಪ್ರೋಗ್ರಾಂ ವಿಕಾಸದ ವಿವಿಧ ಹಂತಗಳನ್ನು ಗುರುತಿಸಲು ನಾವು ಆವೃತ್ತಿಗಳನ್ನು ಬಳಸುತ್ತೇವೆ. ಕಾನ್ಫಿಗರೇಶನ್‌ಗಳ ವಿಭಿನ್ನ ಆವೃತ್ತಿಗಳನ್ನು ಗುರುತಿಸಲು ಇದು ತಾರ್ಕಿಕವಾಗಿ ತೋರುತ್ತದೆ. ಮತ್ತು ಸಂರಚನೆಯನ್ನು ಆವೃತ್ತಿ ನಿಯಂತ್ರಣ ವ್ಯವಸ್ಥೆಯಲ್ಲಿ ಇರಿಸಿ. ಉತ್ಪಾದನೆಯಲ್ಲಿ ಕೇವಲ ಒಂದು ಕಾನ್ಫಿಗರೇಶನ್ ಇದ್ದರೆ, ನಾವು ಆವೃತ್ತಿ ಸಂಖ್ಯೆಯನ್ನು ಸರಳವಾಗಿ ಬಳಸಬಹುದು. ನಾವು ಅನೇಕ ಉತ್ಪಾದನಾ ನಿದರ್ಶನಗಳನ್ನು ಬಳಸಿದರೆ, ನಮಗೆ ಹಲವಾರು ಅಗತ್ಯವಿರುತ್ತದೆ
ಸಂರಚನಾ ಶಾಖೆಗಳು ಮತ್ತು ಆವೃತ್ತಿಯ ಜೊತೆಗೆ ಹೆಚ್ಚುವರಿ ಲೇಬಲ್ (ಉದಾಹರಣೆಗೆ, ಶಾಖೆಯ ಹೆಸರು). ಈ ರೀತಿಯಾಗಿ ನಾವು ನಿಖರವಾದ ಸಂರಚನೆಯನ್ನು ಸ್ಪಷ್ಟವಾಗಿ ಗುರುತಿಸಬಹುದು. ಪ್ರತಿಯೊಂದು ಕಾನ್ಫಿಗರೇಶನ್ ಐಡೆಂಟಿಫೈಯರ್ ವಿತರಣಾ ನೋಡ್‌ಗಳು, ಪೋರ್ಟ್‌ಗಳು, ಬಾಹ್ಯ ಸಂಪನ್ಮೂಲಗಳು ಮತ್ತು ಲೈಬ್ರರಿ ಆವೃತ್ತಿಗಳ ನಿರ್ದಿಷ್ಟ ಸಂಯೋಜನೆಗೆ ಅನನ್ಯವಾಗಿ ಅನುರೂಪವಾಗಿದೆ. ಈ ಪೋಸ್ಟ್‌ನ ಉದ್ದೇಶಗಳಿಗಾಗಿ ನಾವು ಕೇವಲ ಒಂದು ಶಾಖೆ ಎಂದು ಭಾವಿಸುತ್ತೇವೆ ಮತ್ತು ಡಾಟ್ (1.2.3) ನಿಂದ ಪ್ರತ್ಯೇಕಿಸಲಾದ ಮೂರು ಸಂಖ್ಯೆಗಳನ್ನು ಬಳಸಿಕೊಂಡು ನಾವು ಸಾಮಾನ್ಯ ರೀತಿಯಲ್ಲಿ ಸಂರಚನೆಯನ್ನು ಗುರುತಿಸಬಹುದು.

ಆಧುನಿಕ ಪರಿಸರದಲ್ಲಿ, ಸಂರಚನಾ ಕಡತಗಳನ್ನು ಅಪರೂಪವಾಗಿ ಕೈಯಾರೆ ರಚಿಸಲಾಗುತ್ತದೆ. ಹೆಚ್ಚಾಗಿ ಅವು ನಿಯೋಜನೆಯ ಸಮಯದಲ್ಲಿ ಉತ್ಪತ್ತಿಯಾಗುತ್ತವೆ ಮತ್ತು ಇನ್ನು ಮುಂದೆ ಮುಟ್ಟುವುದಿಲ್ಲ (ಆದ್ದರಿಂದ ಏನನ್ನೂ ಮುರಿಯಬೇಡಿ) ಒಂದು ನೈಸರ್ಗಿಕ ಪ್ರಶ್ನೆ ಉದ್ಭವಿಸುತ್ತದೆ: ಸಂರಚನೆಯನ್ನು ಸಂಗ್ರಹಿಸಲು ನಾವು ಇನ್ನೂ ಪಠ್ಯ ಸ್ವರೂಪವನ್ನು ಏಕೆ ಬಳಸುತ್ತೇವೆ? ಒಂದು ಕಾರ್ಯಸಾಧ್ಯವಾದ ಪರ್ಯಾಯವು ಸಂರಚನೆಗಾಗಿ ನಿಯಮಿತ ಕೋಡ್ ಅನ್ನು ಬಳಸುವ ಸಾಮರ್ಥ್ಯ ಮತ್ತು ಕಂಪೈಲ್-ಟೈಮ್ ಚೆಕ್‌ಗಳಿಂದ ಪ್ರಯೋಜನವನ್ನು ತೋರುತ್ತದೆ.

ಈ ಪೋಸ್ಟ್‌ನಲ್ಲಿ ನಾವು ಸಂಕಲಿಸಿದ ಕಲಾಕೃತಿಯೊಳಗೆ ಸಂರಚನೆಯನ್ನು ಪ್ರತಿನಿಧಿಸುವ ಕಲ್ಪನೆಯನ್ನು ಅನ್ವೇಷಿಸುತ್ತೇವೆ.

ಸಂಕಲನ ಸಂರಚನೆ

ಈ ವಿಭಾಗವು ಸ್ಥಿರ ಸಂಕಲನ ಸಂರಚನೆಯ ಉದಾಹರಣೆಯನ್ನು ಒದಗಿಸುತ್ತದೆ. ಎರಡು ಸರಳ ಸೇವೆಗಳನ್ನು ಅಳವಡಿಸಲಾಗಿದೆ - ಪ್ರತಿಧ್ವನಿ ಸೇವೆ ಮತ್ತು ಪ್ರತಿಧ್ವನಿ ಸೇವೆ ಕ್ಲೈಂಟ್. ಈ ಎರಡು ಸೇವೆಗಳ ಆಧಾರದ ಮೇಲೆ, ಎರಡು ಸಿಸ್ಟಮ್ ಆಯ್ಕೆಗಳನ್ನು ಜೋಡಿಸಲಾಗಿದೆ. ಒಂದು ಆಯ್ಕೆಯಲ್ಲಿ, ಎರಡೂ ಸೇವೆಗಳು ಒಂದೇ ನೋಡ್‌ನಲ್ಲಿವೆ, ಇನ್ನೊಂದು ಆಯ್ಕೆಯಲ್ಲಿ - ವಿಭಿನ್ನ ನೋಡ್‌ಗಳಲ್ಲಿ.

ವಿಶಿಷ್ಟವಾಗಿ ವಿತರಿಸಿದ ವ್ಯವಸ್ಥೆಯು ಹಲವಾರು ನೋಡ್‌ಗಳನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಕೆಲವು ಪ್ರಕಾರದ ಮೌಲ್ಯಗಳನ್ನು ಬಳಸಿಕೊಂಡು ನೀವು ನೋಡ್‌ಗಳನ್ನು ಗುರುತಿಸಬಹುದು NodeId:

sealed trait NodeId
case object Backend extends NodeId
case object Frontend extends NodeId

ಅಥವಾ

case class NodeId(hostName: String)

ಅಥವಾ

object Singleton
type NodeId = Singleton.type

ನೋಡ್‌ಗಳು ವಿವಿಧ ಪಾತ್ರಗಳನ್ನು ನಿರ್ವಹಿಸುತ್ತವೆ, ಅವು ಸೇವೆಗಳನ್ನು ನಡೆಸುತ್ತವೆ ಮತ್ತು ಅವುಗಳ ನಡುವೆ TCP/HTTP ಸಂಪರ್ಕಗಳನ್ನು ಸ್ಥಾಪಿಸಬಹುದು.

TCP ಸಂಪರ್ಕವನ್ನು ವಿವರಿಸಲು ನಮಗೆ ಕನಿಷ್ಠ ಪೋರ್ಟ್ ಸಂಖ್ಯೆಯ ಅಗತ್ಯವಿದೆ. ಕ್ಲೈಂಟ್ ಮತ್ತು ಸರ್ವರ್ ಎರಡೂ ಒಂದೇ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಬಳಸುತ್ತಿರುವುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ಆ ಪೋರ್ಟ್‌ನಲ್ಲಿ ಬೆಂಬಲಿತವಾದ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಪ್ರತಿಬಿಂಬಿಸಲು ನಾವು ಬಯಸುತ್ತೇವೆ. ಕೆಳಗಿನ ವರ್ಗವನ್ನು ಬಳಸಿಕೊಂಡು ನಾವು ಸಂಪರ್ಕವನ್ನು ವಿವರಿಸುತ್ತೇವೆ:

case class TcpEndPoint[Protocol](node: NodeId, port: Port[Protocol])

ಅಲ್ಲಿ Port - ಕೇವಲ ಒಂದು ಪೂರ್ಣಾಂಕ Int ಸ್ವೀಕಾರಾರ್ಹ ಮೌಲ್ಯಗಳ ಶ್ರೇಣಿಯನ್ನು ಸೂಚಿಸುತ್ತದೆ:

type PortNumber = Refined[Int, Closed[_0, W.`65535`.T]]

ಸಂಸ್ಕರಿಸಿದ ವಿಧಗಳು

ಲೈಬ್ರರಿ ನೋಡಿ ಸಂಸ್ಕರಿಸಿದ и ನನ್ನ ವರದಿ. ಸಂಕ್ಷಿಪ್ತವಾಗಿ, ಕಂಪೈಲ್ ಸಮಯದಲ್ಲಿ ಪರಿಶೀಲಿಸಲಾದ ಪ್ರಕಾರಗಳಿಗೆ ನಿರ್ಬಂಧಗಳನ್ನು ಸೇರಿಸಲು ಗ್ರಂಥಾಲಯವು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಮಾನ್ಯವಾದ ಪೋರ್ಟ್ ಸಂಖ್ಯೆ ಮೌಲ್ಯಗಳು 16-ಬಿಟ್ ಪೂರ್ಣಾಂಕಗಳಾಗಿವೆ. ಸಂಕಲಿಸಿದ ಸಂರಚನೆಗಾಗಿ, ಸಂಸ್ಕರಿಸಿದ ಲೈಬ್ರರಿಯನ್ನು ಬಳಸುವುದು ಕಡ್ಡಾಯವಲ್ಲ, ಆದರೆ ಇದು ಸಂರಚನೆಯನ್ನು ಪರಿಶೀಲಿಸುವ ಕಂಪೈಲರ್‌ನ ಸಾಮರ್ಥ್ಯವನ್ನು ಸುಧಾರಿಸುತ್ತದೆ.

HTTP (REST) ​​ಪ್ರೋಟೋಕಾಲ್‌ಗಳಿಗಾಗಿ, ಪೋರ್ಟ್ ಸಂಖ್ಯೆಯ ಜೊತೆಗೆ, ನಮಗೆ ಸೇವೆಯ ಮಾರ್ಗವೂ ಬೇಕಾಗಬಹುದು:

type UrlPathPrefix = Refined[String, MatchesRegex[W.`"[a-zA-Z_0-9/]*"`.T]]
case class PortWithPrefix[Protocol](portNumber: PortNumber, pathPrefix: UrlPathPrefix)

ಫ್ಯಾಂಟಮ್ ವಿಧಗಳು

ಕಂಪೈಲ್ ಸಮಯದಲ್ಲಿ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಗುರುತಿಸಲು, ನಾವು ವರ್ಗದೊಳಗೆ ಬಳಸದ ಟೈಪ್ ಪ್ಯಾರಾಮೀಟರ್ ಅನ್ನು ಬಳಸುತ್ತೇವೆ. ರನ್‌ಟೈಮ್‌ನಲ್ಲಿ ನಾವು ಪ್ರೋಟೋಕಾಲ್ ನಿದರ್ಶನವನ್ನು ಬಳಸದಿರುವ ಕಾರಣದಿಂದಾಗಿ ಈ ನಿರ್ಧಾರವಾಗಿದೆ, ಆದರೆ ಕಂಪೈಲರ್ ಪ್ರೋಟೋಕಾಲ್ ಹೊಂದಾಣಿಕೆಯನ್ನು ಪರಿಶೀಲಿಸಲು ನಾವು ಬಯಸುತ್ತೇವೆ. ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸುವ ಮೂಲಕ, ನಮಗೆ ಸೂಕ್ತವಲ್ಲದ ಸೇವೆಯನ್ನು ಅವಲಂಬನೆಯಾಗಿ ರವಾನಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ.

ಸಾಮಾನ್ಯ ಪ್ರೋಟೋಕಾಲ್‌ಗಳಲ್ಲಿ ಒಂದು Json ಧಾರಾವಾಹಿಯೊಂದಿಗೆ REST API ಆಗಿದೆ:

sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]

ಅಲ್ಲಿ RequestMessage - ವಿನಂತಿಯ ಪ್ರಕಾರ, ResponseMessage - ಪ್ರತಿಕ್ರಿಯೆ ಪ್ರಕಾರ.
ಸಹಜವಾಗಿ, ನಮಗೆ ಅಗತ್ಯವಿರುವ ವಿವರಣೆಯ ನಿಖರತೆಯನ್ನು ಒದಗಿಸುವ ಇತರ ಪ್ರೋಟೋಕಾಲ್ ವಿವರಣೆಗಳನ್ನು ನಾವು ಬಳಸಬಹುದು.

ಈ ಪೋಸ್ಟ್‌ನ ಉದ್ದೇಶಗಳಿಗಾಗಿ, ನಾವು ಪ್ರೋಟೋಕಾಲ್‌ನ ಸರಳೀಕೃತ ಆವೃತ್ತಿಯನ್ನು ಬಳಸುತ್ತೇವೆ:

sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]

ಇಲ್ಲಿ ವಿನಂತಿಯು url ಗೆ ಲಗತ್ತಿಸಲಾದ ಸ್ಟ್ರಿಂಗ್ ಆಗಿದೆ ಮತ್ತು ಪ್ರತಿಕ್ರಿಯೆಯು HTTP ಪ್ರತಿಕ್ರಿಯೆಯ ದೇಹದಲ್ಲಿ ಹಿಂತಿರುಗಿದ ಸ್ಟ್ರಿಂಗ್ ಆಗಿದೆ.

ಸೇವೆಯ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಸೇವೆಯ ಹೆಸರು, ಪೋರ್ಟ್‌ಗಳು ಮತ್ತು ಅವಲಂಬನೆಗಳಿಂದ ವಿವರಿಸಲಾಗಿದೆ. ಈ ಅಂಶಗಳನ್ನು ಸ್ಕಾಲಾದಲ್ಲಿ ಹಲವಾರು ವಿಧಗಳಲ್ಲಿ ಪ್ರತಿನಿಧಿಸಬಹುದು (ಉದಾಹರಣೆಗೆ, HList-s, ಬೀಜಗಣಿತದ ಡೇಟಾ ಪ್ರಕಾರಗಳು). ಈ ಪೋಸ್ಟ್‌ನ ಉದ್ದೇಶಗಳಿಗಾಗಿ, ನಾವು ಕೇಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ಬಳಸುತ್ತೇವೆ ಮತ್ತು ಮಾಡ್ಯೂಲ್‌ಗಳನ್ನು ಪ್ರತಿನಿಧಿಸುತ್ತೇವೆ trait'ov. (ಕೇಕ್ ಪ್ಯಾಟರ್ನ್ ಈ ವಿಧಾನದ ಅಗತ್ಯವಿರುವ ಅಂಶವಲ್ಲ. ಇದು ಕೇವಲ ಒಂದು ಸಂಭವನೀಯ ಅನುಷ್ಠಾನವಾಗಿದೆ.)

ಸೇವೆಗಳ ನಡುವಿನ ಅವಲಂಬನೆಗಳನ್ನು ಬಂದರುಗಳನ್ನು ಹಿಂದಿರುಗಿಸುವ ವಿಧಾನಗಳಾಗಿ ಪ್ರತಿನಿಧಿಸಬಹುದು EndPointಇತರ ನೋಡ್‌ಗಳು:

  type EchoProtocol[A] = SimpleHttpGetRest[A, A]

  trait EchoConfig[A] extends ServiceConfig {
    def portNumber: PortNumber = 8081
    def echoPort: PortWithPrefix[EchoProtocol[A]] = PortWithPrefix[EchoProtocol[A]](portNumber, "echo")
    def echoService: HttpSimpleGetEndPoint[NodeId, EchoProtocol[A]] = providedSimpleService(echoPort)
  }

ಪ್ರತಿಧ್ವನಿ ಸೇವೆಯನ್ನು ರಚಿಸಲು, ನಿಮಗೆ ಬೇಕಾಗಿರುವುದು ಪೋರ್ಟ್ ಸಂಖ್ಯೆ ಮತ್ತು ಪೋರ್ಟ್ ಎಕೋ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಬೆಂಬಲಿಸುವ ಸೂಚನೆಯಾಗಿದೆ. ನಾವು ನಿರ್ದಿಷ್ಟ ಪೋರ್ಟ್ ಅನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸದಿರಬಹುದು, ಏಕೆಂದರೆ... ಗುಣಲಕ್ಷಣಗಳು ಅನುಷ್ಠಾನವಿಲ್ಲದೆಯೇ ವಿಧಾನಗಳನ್ನು ಘೋಷಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ (ಅಮೂರ್ತ ವಿಧಾನಗಳು). ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಕಾಂಕ್ರೀಟ್ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ರಚಿಸುವಾಗ, ಕಂಪೈಲರ್ ಅಮೂರ್ತ ವಿಧಾನದ ಅನುಷ್ಠಾನವನ್ನು ಒದಗಿಸಲು ಮತ್ತು ಪೋರ್ಟ್ ಸಂಖ್ಯೆಯನ್ನು ಒದಗಿಸಲು ನಮಗೆ ಅಗತ್ಯವಿರುತ್ತದೆ. ನಾವು ವಿಧಾನವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿರುವುದರಿಂದ, ನಿರ್ದಿಷ್ಟ ಸಂರಚನೆಯನ್ನು ರಚಿಸುವಾಗ, ನಾವು ಬೇರೆ ಪೋರ್ಟ್ ಅನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸದಿರಬಹುದು. ಡೀಫಾಲ್ಟ್ ಮೌಲ್ಯವನ್ನು ಬಳಸಲಾಗುತ್ತದೆ.

ಕ್ಲೈಂಟ್ ಕಾನ್ಫಿಗರೇಶನ್‌ನಲ್ಲಿ ನಾವು ಪ್ರತಿಧ್ವನಿ ಸೇವೆಯ ಮೇಲೆ ಅವಲಂಬನೆಯನ್ನು ಘೋಷಿಸುತ್ತೇವೆ:

  trait EchoClientConfig[A] {
    def testMessage: String = "test"
    def pollInterval: FiniteDuration
    def echoServiceDependency: HttpSimpleGetEndPoint[_, EchoProtocol[A]]
  }

ಅವಲಂಬನೆಯು ರಫ್ತು ಮಾಡಿದ ಸೇವೆಯಂತೆಯೇ ಇರುತ್ತದೆ echoService. ನಿರ್ದಿಷ್ಟವಾಗಿ ಹೇಳುವುದಾದರೆ, ಎಕೋ ಕ್ಲೈಂಟ್‌ನಲ್ಲಿ ನಮಗೆ ಅದೇ ಪ್ರೋಟೋಕಾಲ್ ಅಗತ್ಯವಿರುತ್ತದೆ. ಆದ್ದರಿಂದ, ಎರಡು ಸೇವೆಗಳನ್ನು ಸಂಪರ್ಕಿಸುವಾಗ, ಎಲ್ಲವೂ ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಎಂದು ನಾವು ಖಚಿತವಾಗಿ ಹೇಳಬಹುದು.

ಸೇವೆಗಳ ಅನುಷ್ಠಾನ

ಸೇವೆಯನ್ನು ಪ್ರಾರಂಭಿಸಲು ಮತ್ತು ನಿಲ್ಲಿಸಲು ಒಂದು ಕಾರ್ಯದ ಅಗತ್ಯವಿದೆ. (ಸೇವೆಯನ್ನು ನಿಲ್ಲಿಸುವ ಸಾಮರ್ಥ್ಯವು ಪರೀಕ್ಷೆಗೆ ನಿರ್ಣಾಯಕವಾಗಿದೆ.) ಮತ್ತೆ, ಅಂತಹ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಹಲವಾರು ಆಯ್ಕೆಗಳಿವೆ (ಉದಾಹರಣೆಗೆ, ನಾವು ಕಾನ್ಫಿಗರೇಶನ್ ಪ್ರಕಾರವನ್ನು ಆಧರಿಸಿ ಟೈಪ್ ತರಗತಿಗಳನ್ನು ಬಳಸಬಹುದು). ಈ ಪೋಸ್ಟ್‌ನ ಉದ್ದೇಶಗಳಿಗಾಗಿ ನಾವು ಕೇಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ಬಳಸುತ್ತೇವೆ. ನಾವು ವರ್ಗವನ್ನು ಬಳಸಿಕೊಂಡು ಸೇವೆಯನ್ನು ಪ್ರತಿನಿಧಿಸುತ್ತೇವೆ cats.Resource, ಏಕೆಂದರೆ ಸಮಸ್ಯೆಗಳ ಸಂದರ್ಭದಲ್ಲಿ ಸಂಪನ್ಮೂಲಗಳ ಬಿಡುಗಡೆಯನ್ನು ಸುರಕ್ಷಿತವಾಗಿ ಖಾತರಿಪಡಿಸುವ ವಿಧಾನಗಳನ್ನು ಈ ವರ್ಗವು ಈಗಾಗಲೇ ಒದಗಿಸುತ್ತದೆ. ಸಂಪನ್ಮೂಲವನ್ನು ಪಡೆಯಲು, ನಾವು ಕಾನ್ಫಿಗರೇಶನ್ ಮತ್ತು ರೆಡಿಮೇಡ್ ರನ್ಟೈಮ್ ಸಂದರ್ಭವನ್ನು ಒದಗಿಸಬೇಕಾಗಿದೆ. ಸೇವೆಯ ಆರಂಭಿಕ ಕಾರ್ಯವು ಈ ರೀತಿ ಕಾಣಿಸಬಹುದು:

  type ResourceReader[F[_], Config, A] = Reader[Config, Resource[F, A]]

  trait ServiceImpl[F[_]] {
    type Config
    def resource(
      implicit
      resolver: AddressResolver[F],
      timer: Timer[F],
      contextShift: ContextShift[F],
      ec: ExecutionContext,
      applicative: Applicative[F]
    ): ResourceReader[F, Config, Unit]
  }

ಅಲ್ಲಿ

  • Config - ಈ ಸೇವೆಗಾಗಿ ಕಾನ್ಫಿಗರೇಶನ್ ಪ್ರಕಾರ
  • AddressResolver - ಇತರ ನೋಡ್‌ಗಳ ವಿಳಾಸಗಳನ್ನು ಕಂಡುಹಿಡಿಯಲು ನಿಮಗೆ ಅನುಮತಿಸುವ ರನ್‌ಟೈಮ್ ಆಬ್ಜೆಕ್ಟ್ (ಕೆಳಗೆ ನೋಡಿ)

ಮತ್ತು ಗ್ರಂಥಾಲಯದಿಂದ ಇತರ ಪ್ರಕಾರಗಳು cats:

  • F[_] - ಪರಿಣಾಮದ ಪ್ರಕಾರ (ಸರಳವಾದ ಸಂದರ್ಭದಲ್ಲಿ F[A] ಕೇವಲ ಒಂದು ಕಾರ್ಯವಾಗಿರಬಹುದು () => A. ಈ ಪೋಸ್ಟ್ನಲ್ಲಿ ನಾವು ಬಳಸುತ್ತೇವೆ cats.IO.)
  • Reader[A,B] - ಕಾರ್ಯಕ್ಕೆ ಹೆಚ್ಚು ಅಥವಾ ಕಡಿಮೆ ಸಮಾನಾರ್ಥಕ A => B
  • cats.Resource - ಪಡೆಯಬಹುದಾದ ಮತ್ತು ಬಿಡುಗಡೆ ಮಾಡಬಹುದಾದ ಸಂಪನ್ಮೂಲ
  • Timer - ಟೈಮರ್ (ಸ್ವಲ್ಪ ನಿದ್ರಿಸಲು ಮತ್ತು ಸಮಯದ ಮಧ್ಯಂತರಗಳನ್ನು ಅಳೆಯಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ)
  • ContextShift - ಅನಲಾಗ್ ExecutionContext
  • Applicative - ಪ್ರತ್ಯೇಕ ಪರಿಣಾಮಗಳನ್ನು (ಬಹುತೇಕ ಮೊನಾಡ್) ಸಂಯೋಜಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುವ ಪರಿಣಾಮದ ಪ್ರಕಾರದ ವರ್ಗ. ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾದ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಲ್ಲಿ ಇದನ್ನು ಬಳಸುವುದು ಉತ್ತಮ ಎಂದು ತೋರುತ್ತದೆ Monad/ConcurrentEffect.

ಈ ಫಂಕ್ಷನ್ ಸಿಗ್ನೇಚರ್ ಅನ್ನು ಬಳಸಿಕೊಂಡು ನಾವು ಹಲವಾರು ಸೇವೆಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಬಹುದು. ಉದಾಹರಣೆಗೆ, ಏನನ್ನೂ ಮಾಡದ ಸೇವೆ:

  trait ZeroServiceImpl[F[_]] extends ServiceImpl[F] {
    type Config <: Any
    def resource(...): ResourceReader[F, Config, Unit] =
      Reader(_ => Resource.pure[F, Unit](()))
  }

(ಸೆಂ. ಮೂಲ, ಇದರಲ್ಲಿ ಇತರ ಸೇವೆಗಳನ್ನು ಅಳವಡಿಸಲಾಗಿದೆ - ಪ್ರತಿಧ್ವನಿ ಸೇವೆ, ಪ್ರತಿಧ್ವನಿ ಕ್ಲೈಂಟ್
и ಜೀವಿತಾವಧಿ ನಿಯಂತ್ರಕರು.)

ನೋಡ್ ಎನ್ನುವುದು ಹಲವಾರು ಸೇವೆಗಳನ್ನು ಪ್ರಾರಂಭಿಸಬಹುದಾದ ವಸ್ತುವಾಗಿದೆ (ಸಂಪನ್ಮೂಲಗಳ ಸರಪಳಿಯ ಉಡಾವಣೆಯು ಕೇಕ್ ಪ್ಯಾಟರ್ನ್‌ನಿಂದ ಖಾತ್ರಿಪಡಿಸಲ್ಪಡುತ್ತದೆ):

object SingleNodeImpl extends ZeroServiceImpl[IO]
  with EchoServiceService
  with EchoClientService
  with FiniteDurationLifecycleServiceImpl
{
  type Config = EchoConfig[String] with EchoClientConfig[String] with FiniteDurationLifecycleConfig
}

ಈ ನೋಡ್‌ಗೆ ಅಗತ್ಯವಿರುವ ನಿಖರವಾದ ಕಾನ್ಫಿಗರೇಶನ್ ಪ್ರಕಾರವನ್ನು ನಾವು ನಿರ್ದಿಷ್ಟಪಡಿಸುತ್ತಿದ್ದೇವೆ ಎಂಬುದನ್ನು ದಯವಿಟ್ಟು ಗಮನಿಸಿ. ನಿರ್ದಿಷ್ಟ ಸೇವೆಗೆ ಅಗತ್ಯವಿರುವ ಕಾನ್ಫಿಗರೇಶನ್ ಪ್ರಕಾರಗಳಲ್ಲಿ ಒಂದನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಲು ನಾವು ಮರೆತರೆ, ಸಂಕಲನ ದೋಷವಿರುತ್ತದೆ. ಅಲ್ಲದೆ, ಅಗತ್ಯವಿರುವ ಎಲ್ಲಾ ಡೇಟಾದೊಂದಿಗೆ ಸೂಕ್ತವಾದ ಪ್ರಕಾರದ ಕೆಲವು ವಸ್ತುವನ್ನು ನಾವು ಒದಗಿಸದ ಹೊರತು ನಾವು ನೋಡ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ.

ಹೋಸ್ಟ್ ಹೆಸರು ರೆಸಲ್ಯೂಶನ್

ರಿಮೋಟ್ ಹೋಸ್ಟ್‌ಗೆ ಸಂಪರ್ಕಿಸಲು, ನಮಗೆ ನಿಜವಾದ IP ವಿಳಾಸದ ಅಗತ್ಯವಿದೆ. ಉಳಿದ ಸಂರಚನೆಗಿಂತ ನಂತರ ವಿಳಾಸವು ತಿಳಿಯುವ ಸಾಧ್ಯತೆಯಿದೆ. ಆದ್ದರಿಂದ ನಮಗೆ ನೋಡ್ ಐಡಿಯನ್ನು ವಿಳಾಸಕ್ಕೆ ಮ್ಯಾಪ್ ಮಾಡುವ ಕಾರ್ಯದ ಅಗತ್ಯವಿದೆ:

case class NodeAddress[NodeId](host: Uri.Host)
trait AddressResolver[F[_]] {
  def resolve[NodeId](nodeId: NodeId): F[NodeAddress[NodeId]]
}

ಈ ಕಾರ್ಯವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಹಲವಾರು ಮಾರ್ಗಗಳಿವೆ:

  1. ನಿಯೋಜನೆಯ ಮೊದಲು ವಿಳಾಸಗಳು ನಮಗೆ ತಿಳಿದಿದ್ದರೆ, ನಂತರ ನಾವು ಸ್ಕಾಲಾ ಕೋಡ್ ಅನ್ನು ರಚಿಸಬಹುದು
    ವಿಳಾಸಗಳು ಮತ್ತು ನಂತರ ನಿರ್ಮಾಣವನ್ನು ರನ್ ಮಾಡಿ. ಇದು ಕಂಪೈಲ್ ಮತ್ತು ಪರೀಕ್ಷೆಗಳನ್ನು ನಡೆಸುತ್ತದೆ.
    ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಕಾರ್ಯವನ್ನು ಸ್ಥಿರವಾಗಿ ತಿಳಿಯಲಾಗುತ್ತದೆ ಮತ್ತು ಮ್ಯಾಪಿಂಗ್ ಆಗಿ ಕೋಡ್‌ನಲ್ಲಿ ಪ್ರತಿನಿಧಿಸಬಹುದು Map[NodeId, NodeAddress].
  2. ಕೆಲವು ಸಂದರ್ಭಗಳಲ್ಲಿ, ನೋಡ್ ಪ್ರಾರಂಭವಾದ ನಂತರವೇ ನಿಜವಾದ ವಿಳಾಸವನ್ನು ತಿಳಿಯಲಾಗುತ್ತದೆ.
    ಈ ಸಂದರ್ಭದಲ್ಲಿ, ನಾವು ಇತರ ನೋಡ್‌ಗಳ ಮೊದಲು ಚಲಿಸುವ "ಡಿಸ್ಕವರಿ ಸೇವೆ" ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಬಹುದು ಮತ್ತು ಎಲ್ಲಾ ನೋಡ್‌ಗಳು ಈ ಸೇವೆಯೊಂದಿಗೆ ನೋಂದಾಯಿಸಿಕೊಳ್ಳುತ್ತವೆ ಮತ್ತು ಇತರ ನೋಡ್‌ಗಳ ವಿಳಾಸಗಳನ್ನು ವಿನಂತಿಸುತ್ತವೆ.
  3. ನಾವು ಮಾರ್ಪಡಿಸಬಹುದಾದರೆ /etc/hosts, ನಂತರ ನೀವು ಪೂರ್ವನಿರ್ಧರಿತ ಹೋಸ್ಟ್ ಹೆಸರುಗಳನ್ನು ಬಳಸಬಹುದು (ಹಾಗೆ my-project-main-node и echo-backend) ಮತ್ತು ಈ ಹೆಸರುಗಳನ್ನು ಸರಳವಾಗಿ ಲಿಂಕ್ ಮಾಡಿ
    ನಿಯೋಜನೆಯ ಸಮಯದಲ್ಲಿ IP ವಿಳಾಸಗಳೊಂದಿಗೆ.

ಈ ಪೋಸ್ಟ್‌ನಲ್ಲಿ ನಾವು ಈ ಪ್ರಕರಣಗಳನ್ನು ಹೆಚ್ಚು ವಿವರವಾಗಿ ಪರಿಗಣಿಸುವುದಿಲ್ಲ. ನಮಗಾಗಿ
ಆಟಿಕೆ ಉದಾಹರಣೆಯಲ್ಲಿ, ಎಲ್ಲಾ ನೋಡ್‌ಗಳು ಒಂದೇ IP ವಿಳಾಸವನ್ನು ಹೊಂದಿರುತ್ತವೆ - 127.0.0.1.

ಮುಂದೆ, ವಿತರಿಸಿದ ವ್ಯವಸ್ಥೆಗಾಗಿ ನಾವು ಎರಡು ಆಯ್ಕೆಗಳನ್ನು ಪರಿಗಣಿಸುತ್ತೇವೆ:

  1. ಎಲ್ಲಾ ಸೇವೆಗಳನ್ನು ಒಂದು ನೋಡ್‌ನಲ್ಲಿ ಇರಿಸಲಾಗುತ್ತಿದೆ.
  2. ಮತ್ತು ವಿವಿಧ ನೋಡ್‌ಗಳಲ್ಲಿ ಪ್ರತಿಧ್ವನಿ ಸೇವೆ ಮತ್ತು ಪ್ರತಿಧ್ವನಿ ಕ್ಲೈಂಟ್ ಅನ್ನು ಹೋಸ್ಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ.

ಫಾರ್ ಕಾನ್ಫಿಗರೇಶನ್ ಒಂದು ನೋಡ್:

ಏಕ ನೋಡ್ ಕಾನ್ಫಿಗರೇಶನ್

object SingleNodeConfig extends EchoConfig[String] 
  with EchoClientConfig[String] with FiniteDurationLifecycleConfig
{
  case object Singleton // identifier of the single node 
  // configuration of server
  type NodeId = Singleton.type
  def nodeId = Singleton

  /** Type safe service port specification. */
  override def portNumber: PortNumber = 8088

  // configuration of client

  /** We'll use the service provided by the same host. */
  def echoServiceDependency = echoService

  override def testMessage: UrlPathElement = "hello"

  def pollInterval: FiniteDuration = 1.second

  // lifecycle controller configuration
  def lifetime: FiniteDuration = 10500.milliseconds // additional 0.5 seconds so that there are 10 requests, not 9.
}

ವಸ್ತುವು ಕ್ಲೈಂಟ್ ಮತ್ತು ಸರ್ವರ್ ಎರಡರ ಸಂರಚನೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತದೆ. ಟೈಮ್-ಟು-ಲೈವ್ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಸಹ ಬಳಸಲಾಗುತ್ತದೆ ಆದ್ದರಿಂದ ಮಧ್ಯಂತರದ ನಂತರ lifetime ಕಾರ್ಯಕ್ರಮವನ್ನು ಮುಕ್ತಾಯಗೊಳಿಸಿ. (Ctrl-C ಎಲ್ಲಾ ಸಂಪನ್ಮೂಲಗಳನ್ನು ಸರಿಯಾಗಿ ಕೆಲಸ ಮಾಡುತ್ತದೆ ಮತ್ತು ಮುಕ್ತಗೊಳಿಸುತ್ತದೆ.)

ಒಳಗೊಂಡಿರುವ ವ್ಯವಸ್ಥೆಯನ್ನು ರಚಿಸಲು ಅದೇ ರೀತಿಯ ಸಂರಚನೆ ಮತ್ತು ಅನುಷ್ಠಾನದ ಲಕ್ಷಣಗಳನ್ನು ಬಳಸಬಹುದು ಎರಡು ಪ್ರತ್ಯೇಕ ನೋಡ್ಗಳು:

ಎರಡು ನೋಡ್ ಕಾನ್ಫಿಗರೇಶನ್

  object NodeServerConfig extends EchoConfig[String] with SigTermLifecycleConfig
  {
    type NodeId = NodeIdImpl

    def nodeId = NodeServer

    override def portNumber: PortNumber = 8080
  }

  object NodeClientConfig extends EchoClientConfig[String] with FiniteDurationLifecycleConfig
  {
    // NB! dependency specification
    def echoServiceDependency = NodeServerConfig.echoService

    def pollInterval: FiniteDuration = 1.second

    def lifetime: FiniteDuration = 10500.milliseconds // additional 0.5 seconds so that there are 10 request, not 9.

    def testMessage: String = "dolly"
  }

ಪ್ರಮುಖ! ಸೇವೆಗಳನ್ನು ಹೇಗೆ ಲಿಂಕ್ ಮಾಡಲಾಗಿದೆ ಎಂಬುದನ್ನು ಗಮನಿಸಿ. ಒಂದು ನೋಡ್‌ನಿಂದ ಕಾರ್ಯಗತಗೊಳಿಸಿದ ಸೇವೆಯನ್ನು ನಾವು ಇನ್ನೊಂದು ನೋಡ್‌ನ ಅವಲಂಬನೆ ವಿಧಾನದ ಅನುಷ್ಠಾನವಾಗಿ ನಿರ್ದಿಷ್ಟಪಡಿಸುತ್ತೇವೆ. ಅವಲಂಬನೆ ಪ್ರಕಾರವನ್ನು ಕಂಪೈಲರ್‌ನಿಂದ ಪರಿಶೀಲಿಸಲಾಗುತ್ತದೆ, ಏಕೆಂದರೆ ಪ್ರೋಟೋಕಾಲ್ ಪ್ರಕಾರವನ್ನು ಒಳಗೊಂಡಿದೆ. ರನ್ ಮಾಡಿದಾಗ, ಅವಲಂಬನೆಯು ಸರಿಯಾದ ಗುರಿ ನೋಡ್ ಐಡಿಯನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಈ ಯೋಜನೆಗೆ ಧನ್ಯವಾದಗಳು, ನಾವು ಪೋರ್ಟ್ ಸಂಖ್ಯೆಯನ್ನು ನಿಖರವಾಗಿ ಒಮ್ಮೆ ನಿರ್ದಿಷ್ಟಪಡಿಸುತ್ತೇವೆ ಮತ್ತು ಸರಿಯಾದ ಪೋರ್ಟ್ ಅನ್ನು ಉಲ್ಲೇಖಿಸಲು ಯಾವಾಗಲೂ ಭರವಸೆ ನೀಡುತ್ತೇವೆ.

ಎರಡು ಸಿಸ್ಟಮ್ ನೋಡ್ಗಳ ಅನುಷ್ಠಾನ

ಈ ಕಾನ್ಫಿಗರೇಶನ್‌ಗಾಗಿ, ನಾವು ಬದಲಾವಣೆಗಳಿಲ್ಲದೆ ಅದೇ ಸೇವೆಯ ಅನುಷ್ಠಾನಗಳನ್ನು ಬಳಸುತ್ತೇವೆ. ಒಂದೇ ವ್ಯತ್ಯಾಸವೆಂದರೆ ನಾವು ಈಗ ವಿಭಿನ್ನ ಸೇವೆಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ಎರಡು ವಸ್ತುಗಳನ್ನು ಹೊಂದಿದ್ದೇವೆ:

  object TwoJvmNodeServerImpl extends ZeroServiceImpl[IO] with EchoServiceService with SigIntLifecycleServiceImpl {
    type Config = EchoConfig[String] with SigTermLifecycleConfig
  }

  object TwoJvmNodeClientImpl extends ZeroServiceImpl[IO] with EchoClientService with FiniteDurationLifecycleServiceImpl {
    type Config = EchoClientConfig[String] with FiniteDurationLifecycleConfig
  }

ಮೊದಲ ನೋಡ್ ಸರ್ವರ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ಸರ್ವರ್ ಕಾನ್ಫಿಗರೇಶನ್ ಮಾತ್ರ ಅಗತ್ಯವಿದೆ. ಎರಡನೇ ನೋಡ್ ಕ್ಲೈಂಟ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ಕಾನ್ಫಿಗರೇಶನ್‌ನ ವಿಭಿನ್ನ ಭಾಗವನ್ನು ಬಳಸುತ್ತದೆ. ಅಲ್ಲದೆ ಎರಡೂ ನೋಡ್‌ಗಳಿಗೆ ಜೀವಿತಾವಧಿ ನಿರ್ವಹಣೆಯ ಅಗತ್ಯವಿದೆ. ಸರ್ವರ್ ನೋಡ್ ಅದನ್ನು ನಿಲ್ಲಿಸುವವರೆಗೆ ಅನಿರ್ದಿಷ್ಟವಾಗಿ ಚಲಿಸುತ್ತದೆ SIGTERM'ಓಂ, ಮತ್ತು ಕ್ಲೈಂಟ್ ನೋಡ್ ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ ಕೊನೆಗೊಳ್ಳುತ್ತದೆ. ಸೆಂ. ಲಾಂಚರ್ ಅಪ್ಲಿಕೇಶನ್.

ಸಾಮಾನ್ಯ ಅಭಿವೃದ್ಧಿ ಪ್ರಕ್ರಿಯೆ

ಈ ಸಂರಚನಾ ವಿಧಾನವು ಒಟ್ಟಾರೆ ಅಭಿವೃದ್ಧಿ ಪ್ರಕ್ರಿಯೆಯ ಮೇಲೆ ಹೇಗೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ ಎಂಬುದನ್ನು ನೋಡೋಣ.

ಉಳಿದ ಕೋಡ್‌ನೊಂದಿಗೆ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಸಂಕಲಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಕಲಾಕೃತಿಯನ್ನು (.jar) ರಚಿಸಲಾಗುತ್ತದೆ. ಸಂರಚನೆಯನ್ನು ಪ್ರತ್ಯೇಕ ಕಲಾಕೃತಿಯಲ್ಲಿ ಹಾಕಲು ಇದು ಅರ್ಥಪೂರ್ಣವಾಗಿದೆ ಎಂದು ತೋರುತ್ತದೆ. ಏಕೆಂದರೆ ಒಂದೇ ಕೋಡ್‌ನ ಆಧಾರದ ಮೇಲೆ ನಾವು ಅನೇಕ ಕಾನ್ಫಿಗರೇಶನ್‌ಗಳನ್ನು ಹೊಂದಬಹುದು. ಮತ್ತೊಮ್ಮೆ, ವಿವಿಧ ಸಂರಚನಾ ಶಾಖೆಗಳಿಗೆ ಅನುಗುಣವಾದ ಕಲಾಕೃತಿಗಳನ್ನು ರಚಿಸಲು ಸಾಧ್ಯವಿದೆ. ಲೈಬ್ರರಿಗಳ ನಿರ್ದಿಷ್ಟ ಆವೃತ್ತಿಗಳ ಮೇಲಿನ ಅವಲಂಬನೆಗಳನ್ನು ಕಾನ್ಫಿಗರೇಶನ್ ಜೊತೆಗೆ ಉಳಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ನಾವು ಕಾನ್ಫಿಗರೇಶನ್‌ನ ಆ ಆವೃತ್ತಿಯನ್ನು ನಿಯೋಜಿಸಲು ನಿರ್ಧರಿಸಿದಾಗ ಈ ಆವೃತ್ತಿಗಳನ್ನು ಶಾಶ್ವತವಾಗಿ ಉಳಿಸಲಾಗುತ್ತದೆ.

ಯಾವುದೇ ಕಾನ್ಫಿಗರೇಶನ್ ಬದಲಾವಣೆಯು ಕೋಡ್ ಬದಲಾವಣೆಯಾಗಿ ಬದಲಾಗುತ್ತದೆ. ಮತ್ತು ಆದ್ದರಿಂದ, ಪ್ರತಿ
ಬದಲಾವಣೆಯು ಸಾಮಾನ್ಯ ಗುಣಮಟ್ಟದ ಭರವಸೆ ಪ್ರಕ್ರಿಯೆಯಿಂದ ಆವರಿಸಲ್ಪಡುತ್ತದೆ:

ಬಗ್ ಟ್ರ್ಯಾಕರ್‌ನಲ್ಲಿ ಟಿಕೆಟ್ -> PR -> ವಿಮರ್ಶೆ -> ಸಂಬಂಧಿತ ಶಾಖೆಗಳೊಂದಿಗೆ ವಿಲೀನಗೊಳಿಸಿ ->
ಏಕೀಕರಣ -> ನಿಯೋಜನೆ

ಸಂಕಲಿಸಿದ ಸಂರಚನೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ಮುಖ್ಯ ಪರಿಣಾಮಗಳು:

  1. ವಿತರಣಾ ವ್ಯವಸ್ಥೆಯ ಎಲ್ಲಾ ನೋಡ್‌ಗಳಲ್ಲಿ ಕಾನ್ಫಿಗರೇಶನ್ ಸ್ಥಿರವಾಗಿರುತ್ತದೆ. ಎಲ್ಲಾ ನೋಡ್‌ಗಳು ಒಂದೇ ಮೂಲದಿಂದ ಒಂದೇ ರೀತಿಯ ಸಂರಚನೆಯನ್ನು ಪಡೆಯುತ್ತವೆ ಎಂಬ ಅಂಶದಿಂದಾಗಿ.

  2. ನೋಡ್‌ಗಳಲ್ಲಿ ಒಂದರಲ್ಲಿ ಮಾತ್ರ ಸಂರಚನೆಯನ್ನು ಬದಲಾಯಿಸುವುದು ಸಮಸ್ಯಾತ್ಮಕವಾಗಿದೆ. ಆದ್ದರಿಂದ, "ಕಾನ್ಫಿಗರೇಶನ್ ಡ್ರಿಫ್ಟ್" ಅಸಂಭವವಾಗಿದೆ.

  3. ಸಂರಚನೆಯಲ್ಲಿ ಸಣ್ಣ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡುವುದು ಹೆಚ್ಚು ಕಷ್ಟಕರವಾಗುತ್ತದೆ.

  4. ಒಟ್ಟಾರೆ ಅಭಿವೃದ್ಧಿ ಪ್ರಕ್ರಿಯೆಯ ಭಾಗವಾಗಿ ಹೆಚ್ಚಿನ ಕಾನ್ಫಿಗರೇಶನ್ ಬದಲಾವಣೆಗಳು ಸಂಭವಿಸುತ್ತವೆ ಮತ್ತು ಪರಿಶೀಲನೆಗೆ ಒಳಪಟ್ಟಿರುತ್ತವೆ.

ಉತ್ಪಾದನಾ ಸಂರಚನೆಯನ್ನು ಸಂಗ್ರಹಿಸಲು ನನಗೆ ಪ್ರತ್ಯೇಕ ರೆಪೊಸಿಟರಿ ಅಗತ್ಯವಿದೆಯೇ? ಈ ಕಾನ್ಫಿಗರೇಶನ್ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಮತ್ತು ಇತರ ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರಬಹುದು, ಇವುಗಳಿಗೆ ನಾವು ಪ್ರವೇಶವನ್ನು ನಿರ್ಬಂಧಿಸಲು ಬಯಸುತ್ತೇವೆ. ಇದರ ಆಧಾರದ ಮೇಲೆ, ಅಂತಿಮ ಸಂರಚನೆಯನ್ನು ಪ್ರತ್ಯೇಕ ರೆಪೊಸಿಟರಿಯಲ್ಲಿ ಸಂಗ್ರಹಿಸಲು ಇದು ಅರ್ಥಪೂರ್ಣವಾಗಿದೆ ಎಂದು ತೋರುತ್ತದೆ. ನೀವು ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಎರಡು ಭಾಗಗಳಾಗಿ ವಿಭಜಿಸಬಹುದು-ಒಂದು ಸಾರ್ವಜನಿಕವಾಗಿ ಪ್ರವೇಶಿಸಬಹುದಾದ ಕಾನ್ಫಿಗರೇಶನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ ಮತ್ತು ಒಂದು ನಿರ್ಬಂಧಿತ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ. ಇದು ಹೆಚ್ಚಿನ ಡೆವಲಪರ್‌ಗಳಿಗೆ ಸಾಮಾನ್ಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಪ್ರವೇಶವನ್ನು ಹೊಂದಲು ಅನುಮತಿಸುತ್ತದೆ. ಡೀಫಾಲ್ಟ್ ಮೌಲ್ಯಗಳನ್ನು ಹೊಂದಿರುವ ಮಧ್ಯಂತರ ಲಕ್ಷಣಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಈ ಪ್ರತ್ಯೇಕತೆಯನ್ನು ಸಾಧಿಸುವುದು ಸುಲಭ.

ಸಂಭವನೀಯ ವ್ಯತ್ಯಾಸಗಳು

ಸಂಕಲಿಸಿದ ಸಂರಚನೆಯನ್ನು ಕೆಲವು ಸಾಮಾನ್ಯ ಪರ್ಯಾಯಗಳೊಂದಿಗೆ ಹೋಲಿಸಲು ಪ್ರಯತ್ನಿಸೋಣ:

  1. ಗುರಿ ಯಂತ್ರದಲ್ಲಿ ಪಠ್ಯ ಫೈಲ್.
  2. ಕೇಂದ್ರೀಕೃತ ಕೀ-ಮೌಲ್ಯದ ಅಂಗಡಿ (etcd/zookeeper).
  3. ಪ್ರಕ್ರಿಯೆಯನ್ನು ಮರುಪ್ರಾರಂಭಿಸದೆಯೇ ಮರುಸಂರಚಿಸಬಹುದಾದ/ಮರುಪ್ರಾರಂಭಿಸಬಹುದಾದ ಪ್ರಕ್ರಿಯೆ ಘಟಕಗಳು.
  4. ಕಲಾಕೃತಿ ಮತ್ತು ಆವೃತ್ತಿ ನಿಯಂತ್ರಣದ ಹೊರಗೆ ಸಂರಚನೆಯನ್ನು ಸಂಗ್ರಹಿಸುವುದು.

ಸಣ್ಣ ಬದಲಾವಣೆಗಳ ವಿಷಯದಲ್ಲಿ ಪಠ್ಯ ಫೈಲ್‌ಗಳು ಗಮನಾರ್ಹ ನಮ್ಯತೆಯನ್ನು ಒದಗಿಸುತ್ತವೆ. ಸಿಸ್ಟಮ್ ನಿರ್ವಾಹಕರು ರಿಮೋಟ್ ನೋಡ್‌ಗೆ ಲಾಗ್ ಇನ್ ಮಾಡಬಹುದು, ಸೂಕ್ತವಾದ ಫೈಲ್‌ಗಳಿಗೆ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಬಹುದು ಮತ್ತು ಸೇವೆಯನ್ನು ಮರುಪ್ರಾರಂಭಿಸಬಹುದು. ಆದಾಗ್ಯೂ, ದೊಡ್ಡ ವ್ಯವಸ್ಥೆಗಳಿಗೆ, ಅಂತಹ ನಮ್ಯತೆಯು ಅಪೇಕ್ಷಣೀಯವಾಗಿರುವುದಿಲ್ಲ. ಮಾಡಿದ ಬದಲಾವಣೆಗಳು ಇತರ ವ್ಯವಸ್ಥೆಗಳಲ್ಲಿ ಯಾವುದೇ ಕುರುಹುಗಳನ್ನು ಬಿಡುವುದಿಲ್ಲ. ಬದಲಾವಣೆಗಳನ್ನು ಯಾರೂ ಪರಿಶೀಲಿಸುವುದಿಲ್ಲ. ಯಾರು ನಿಖರವಾಗಿ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಿದ್ದಾರೆ ಮತ್ತು ಯಾವ ಕಾರಣಕ್ಕಾಗಿ ನಿರ್ಧರಿಸಲು ಕಷ್ಟ. ಬದಲಾವಣೆಗಳನ್ನು ಪರೀಕ್ಷಿಸಲಾಗಿಲ್ಲ. ಸಿಸ್ಟಮ್ ಅನ್ನು ವಿತರಿಸಿದರೆ, ನಿರ್ವಾಹಕರು ಇತರ ನೋಡ್‌ಗಳಲ್ಲಿ ಅನುಗುಣವಾದ ಬದಲಾವಣೆಯನ್ನು ಮಾಡಲು ಮರೆಯಬಹುದು.

(ಕಂಪೈಲ್ ಮಾಡಿದ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಬಳಸುವುದರಿಂದ ಭವಿಷ್ಯದಲ್ಲಿ ಪಠ್ಯ ಫೈಲ್‌ಗಳನ್ನು ಬಳಸುವ ಸಾಧ್ಯತೆಯನ್ನು ಮುಚ್ಚುವುದಿಲ್ಲ ಎಂಬುದನ್ನು ಸಹ ಗಮನಿಸಬೇಕು. ಔಟ್‌ಪುಟ್‌ನಂತೆಯೇ ಅದೇ ಪ್ರಕಾರವನ್ನು ಉತ್ಪಾದಿಸುವ ಪಾರ್ಸರ್ ಮತ್ತು ವ್ಯಾಲಿಡೇಟರ್ ಅನ್ನು ಸೇರಿಸಲು ಇದು ಸಾಕಾಗುತ್ತದೆ. Config, ಮತ್ತು ನೀವು ಪಠ್ಯ ಫೈಲ್ಗಳನ್ನು ಬಳಸಬಹುದು. ಕಂಪೈಲ್ ಮಾಡಿದ ಕಾನ್ಫಿಗರೇಶನ್ ಹೊಂದಿರುವ ಸಿಸ್ಟಮ್‌ನ ಸಂಕೀರ್ಣತೆಯು ಪಠ್ಯ ಫೈಲ್‌ಗಳನ್ನು ಬಳಸುವ ಸಿಸ್ಟಮ್‌ನ ಸಂಕೀರ್ಣತೆಗಿಂತ ಸ್ವಲ್ಪ ಕಡಿಮೆಯಾಗಿದೆ ಎಂದು ಅದು ತಕ್ಷಣವೇ ಅನುಸರಿಸುತ್ತದೆ, ಏಕೆಂದರೆ ಪಠ್ಯ ಫೈಲ್‌ಗಳಿಗೆ ಹೆಚ್ಚುವರಿ ಕೋಡ್ ಅಗತ್ಯವಿದೆ.)

ವಿತರಿಸಿದ ಅಪ್ಲಿಕೇಶನ್‌ನ ಮೆಟಾ ನಿಯತಾಂಕಗಳನ್ನು ವಿತರಿಸಲು ಕೇಂದ್ರೀಕೃತ ಕೀ-ಮೌಲ್ಯದ ಅಂಗಡಿಯು ಉತ್ತಮ ಕಾರ್ಯವಿಧಾನವಾಗಿದೆ. ಕಾನ್ಫಿಗರೇಶನ್ ಪ್ಯಾರಾಮೀಟರ್‌ಗಳು ಯಾವುವು ಮತ್ತು ಕೇವಲ ಡೇಟಾ ಯಾವುದು ಎಂಬುದನ್ನು ನಾವು ನಿರ್ಧರಿಸಬೇಕು. ನಮಗೆ ಒಂದು ಕಾರ್ಯವನ್ನು ಮಾಡೋಣ C => A => B, ಮತ್ತು ನಿಯತಾಂಕಗಳು C ಅಪರೂಪವಾಗಿ ಬದಲಾವಣೆಗಳು ಮತ್ತು ಡೇಟಾ A - ಆಗಾಗ್ಗೆ. ಈ ಸಂದರ್ಭದಲ್ಲಿ ನಾವು ಹೇಳಬಹುದು C - ಕಾನ್ಫಿಗರೇಶನ್ ನಿಯತಾಂಕಗಳು, ಮತ್ತು A - ಡೇಟಾ. ಕಾನ್ಫಿಗರೇಶನ್ ಪ್ಯಾರಾಮೀಟರ್‌ಗಳು ಡೇಟಾದಿಂದ ಭಿನ್ನವಾಗಿರುತ್ತವೆ, ಅವುಗಳು ಸಾಮಾನ್ಯವಾಗಿ ಡೇಟಾಕ್ಕಿಂತ ಕಡಿಮೆ ಬಾರಿ ಬದಲಾಗುತ್ತವೆ. ಅಲ್ಲದೆ, ಡೇಟಾ ಸಾಮಾನ್ಯವಾಗಿ ಒಂದು ಮೂಲದಿಂದ (ಬಳಕೆದಾರರಿಂದ), ಮತ್ತು ಕಾನ್ಫಿಗರೇಶನ್ ನಿಯತಾಂಕಗಳು ಇನ್ನೊಂದರಿಂದ (ಸಿಸ್ಟಮ್ ನಿರ್ವಾಹಕರಿಂದ) ಬರುತ್ತದೆ.

ಪ್ರೋಗ್ರಾಂ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸದೆಯೇ ಅಪರೂಪವಾಗಿ ಬದಲಾಗುತ್ತಿರುವ ನಿಯತಾಂಕಗಳನ್ನು ನವೀಕರಿಸಬೇಕಾದರೆ, ಇದು ಪ್ರೋಗ್ರಾಂನ ತೊಡಕುಗಳಿಗೆ ಕಾರಣವಾಗಬಹುದು, ಏಕೆಂದರೆ ನಾವು ಹೇಗಾದರೂ ನಿಯತಾಂಕಗಳನ್ನು ತಲುಪಿಸಬೇಕಾಗಿದೆ, ಸಂಗ್ರಹಿಸಿ, ಪಾರ್ಸ್ ಮಾಡಿ ಮತ್ತು ಪರಿಶೀಲಿಸಿ ಮತ್ತು ತಪ್ಪಾದ ಮೌಲ್ಯಗಳನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಬೇಕು. ಆದ್ದರಿಂದ, ಪ್ರೋಗ್ರಾಂನ ಸಂಕೀರ್ಣತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುವ ದೃಷ್ಟಿಕೋನದಿಂದ, ಪ್ರೋಗ್ರಾಂ ಕಾರ್ಯಾಚರಣೆಯ ಸಮಯದಲ್ಲಿ ಬದಲಾಗಬಹುದಾದ ನಿಯತಾಂಕಗಳ ಸಂಖ್ಯೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಲು ಇದು ಅರ್ಥಪೂರ್ಣವಾಗಿದೆ (ಅಥವಾ ಅಂತಹ ನಿಯತಾಂಕಗಳನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ).

ಈ ಪೋಸ್ಟ್‌ನ ಉದ್ದೇಶಗಳಿಗಾಗಿ, ನಾವು ಸ್ಥಿರ ಮತ್ತು ಕ್ರಿಯಾತ್ಮಕ ನಿಯತಾಂಕಗಳ ನಡುವೆ ವ್ಯತ್ಯಾಸವನ್ನು ಮಾಡುತ್ತೇವೆ. ಪ್ರೋಗ್ರಾಂನ ಕಾರ್ಯಾಚರಣೆಯ ಸಮಯದಲ್ಲಿ ಸೇವೆಯ ತರ್ಕವು ನಿಯತಾಂಕಗಳನ್ನು ಬದಲಾಯಿಸುವ ಅಗತ್ಯವಿದ್ದರೆ, ನಾವು ಅಂತಹ ನಿಯತಾಂಕಗಳನ್ನು ಡೈನಾಮಿಕ್ ಎಂದು ಕರೆಯುತ್ತೇವೆ. ಇಲ್ಲದಿದ್ದರೆ ಆಯ್ಕೆಗಳು ಸ್ಥಿರವಾಗಿರುತ್ತವೆ ಮತ್ತು ಸಂಕಲಿಸಿದ ಸಂರಚನೆಯನ್ನು ಬಳಸಿಕೊಂಡು ಕಾನ್ಫಿಗರ್ ಮಾಡಬಹುದು. ಡೈನಾಮಿಕ್ ಮರುಸಂರಚನೆಗಾಗಿ, ಆಪರೇಟಿಂಗ್ ಸಿಸ್ಟಮ್ ಪ್ರಕ್ರಿಯೆಗಳನ್ನು ಹೇಗೆ ಮರುಪ್ರಾರಂಭಿಸಲಾಗುತ್ತದೆ ಎಂಬುದರಂತೆಯೇ ಹೊಸ ನಿಯತಾಂಕಗಳೊಂದಿಗೆ ಪ್ರೋಗ್ರಾಂನ ಭಾಗಗಳನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ನಮಗೆ ಯಾಂತ್ರಿಕತೆಯ ಅಗತ್ಯವಿರಬಹುದು. (ನಮ್ಮ ಅಭಿಪ್ರಾಯದಲ್ಲಿ, ನೈಜ-ಸಮಯದ ಮರುಸಂರಚನೆಯನ್ನು ತಪ್ಪಿಸುವುದು ಸೂಕ್ತವಾಗಿದೆ, ಏಕೆಂದರೆ ಇದು ಸಿಸ್ಟಮ್‌ನ ಸಂಕೀರ್ಣತೆಯನ್ನು ಹೆಚ್ಚಿಸುತ್ತದೆ. ಸಾಧ್ಯವಾದರೆ, ಪ್ರಕ್ರಿಯೆಗಳನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಪ್ರಮಾಣಿತ OS ಸಾಮರ್ಥ್ಯಗಳನ್ನು ಬಳಸುವುದು ಉತ್ತಮ.)

ಸ್ಥಿರ ಸಂರಚನೆಯನ್ನು ಬಳಸುವ ಒಂದು ಪ್ರಮುಖ ಅಂಶವೆಂದರೆ ಜನರು ಡೈನಾಮಿಕ್ ಮರುಸಂರಚನೆಯನ್ನು ಪರಿಗಣಿಸುವಂತೆ ಮಾಡುತ್ತದೆ ಕಾನ್ಫಿಗರೇಶನ್ ನವೀಕರಣದ ನಂತರ ಸಿಸ್ಟಮ್ ರೀಬೂಟ್ ಮಾಡಲು ತೆಗೆದುಕೊಳ್ಳುವ ಸಮಯ (ಅಲಭ್ಯತೆ). ವಾಸ್ತವವಾಗಿ, ನಾವು ಸ್ಥಿರ ಕಾನ್ಫಿಗರೇಶನ್‌ಗೆ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಬೇಕಾದರೆ, ಹೊಸ ಮೌಲ್ಯಗಳು ಕಾರ್ಯರೂಪಕ್ಕೆ ಬರಲು ನಾವು ಸಿಸ್ಟಮ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಬೇಕಾಗುತ್ತದೆ. ಅಲಭ್ಯತೆಯ ಸಮಸ್ಯೆಯು ವಿಭಿನ್ನ ವ್ಯವಸ್ಥೆಗಳಿಗೆ ತೀವ್ರತೆಯಲ್ಲಿ ಬದಲಾಗುತ್ತದೆ. ಕೆಲವು ಸಂದರ್ಭಗಳಲ್ಲಿ, ಲೋಡ್ ಕಡಿಮೆ ಇರುವ ಸಮಯದಲ್ಲಿ ನೀವು ರೀಬೂಟ್ ಅನ್ನು ನಿಗದಿಪಡಿಸಬಹುದು. ನೀವು ನಿರಂತರ ಸೇವೆಯನ್ನು ಒದಗಿಸಬೇಕಾದರೆ, ನೀವು ಕಾರ್ಯಗತಗೊಳಿಸಬಹುದು AWS ELB ಸಂಪರ್ಕ ಬರಿದಾಗುತ್ತಿದೆ. ಅದೇ ಸಮಯದಲ್ಲಿ, ನಾವು ಸಿಸ್ಟಮ್ ಅನ್ನು ರೀಬೂಟ್ ಮಾಡಬೇಕಾದಾಗ, ನಾವು ಈ ಸಿಸ್ಟಮ್ನ ಸಮಾನಾಂತರ ಉದಾಹರಣೆಯನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತೇವೆ, ಅದಕ್ಕೆ ಬ್ಯಾಲೆನ್ಸರ್ ಅನ್ನು ಬದಲಾಯಿಸುತ್ತೇವೆ ಮತ್ತು ಹಳೆಯ ಸಂಪರ್ಕಗಳು ಪೂರ್ಣಗೊಳ್ಳಲು ಕಾಯುತ್ತೇವೆ. ಎಲ್ಲಾ ಹಳೆಯ ಸಂಪರ್ಕಗಳನ್ನು ಕೊನೆಗೊಳಿಸಿದ ನಂತರ, ನಾವು ಸಿಸ್ಟಮ್ನ ಹಳೆಯ ನಿದರ್ಶನವನ್ನು ಸ್ಥಗಿತಗೊಳಿಸುತ್ತೇವೆ.

ಕಲಾಕೃತಿಯ ಒಳಗೆ ಅಥವಾ ಹೊರಗೆ ಸಂರಚನೆಯನ್ನು ಸಂಗ್ರಹಿಸುವ ಸಮಸ್ಯೆಯನ್ನು ನಾವು ಈಗ ಪರಿಗಣಿಸೋಣ. ನಾವು ಕಲಾಕೃತಿಯೊಳಗೆ ಸಂರಚನೆಯನ್ನು ಸಂಗ್ರಹಿಸಿದರೆ, ಕಲಾಕೃತಿಯ ಜೋಡಣೆಯ ಸಮಯದಲ್ಲಿ ಸಂರಚನೆಯ ಸರಿಯಾದತೆಯನ್ನು ಪರಿಶೀಲಿಸಲು ನಮಗೆ ಅವಕಾಶವಿದೆ. ಕಾನ್ಫಿಗರೇಶನ್ ನಿಯಂತ್ರಿತ ಕಲಾಕೃತಿಯಿಂದ ಹೊರಗಿದ್ದರೆ, ಈ ಫೈಲ್‌ಗೆ ಯಾರು ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಿದ್ದಾರೆ ಮತ್ತು ಏಕೆ ಎಂದು ಟ್ರ್ಯಾಕ್ ಮಾಡುವುದು ಕಷ್ಟ. ಇದು ಎಷ್ಟು ಮುಖ್ಯ? ನಮ್ಮ ಅಭಿಪ್ರಾಯದಲ್ಲಿ, ಅನೇಕ ಉತ್ಪಾದನಾ ವ್ಯವಸ್ಥೆಗಳಿಗೆ ಸ್ಥಿರ ಮತ್ತು ಉತ್ತಮ-ಗುಣಮಟ್ಟದ ಸಂರಚನೆಯನ್ನು ಹೊಂದಲು ಮುಖ್ಯವಾಗಿದೆ.

ಕಲಾಕೃತಿಯ ಆವೃತ್ತಿಯು ಅದನ್ನು ಯಾವಾಗ ರಚಿಸಲಾಗಿದೆ, ಅದು ಯಾವ ಮೌಲ್ಯಗಳನ್ನು ಒಳಗೊಂಡಿದೆ, ಯಾವ ಕಾರ್ಯಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ / ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ ಮತ್ತು ಕಾನ್ಫಿಗರೇಶನ್‌ನಲ್ಲಿನ ಯಾವುದೇ ಬದಲಾವಣೆಗೆ ಯಾರು ಜವಾಬ್ದಾರರು ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸಹಜವಾಗಿ, ಕಲಾಕೃತಿಯೊಳಗೆ ಸಂರಚನೆಯನ್ನು ಸಂಗ್ರಹಿಸಲು ಸ್ವಲ್ಪ ಪ್ರಯತ್ನ ಬೇಕಾಗುತ್ತದೆ, ಆದ್ದರಿಂದ ನೀವು ತಿಳುವಳಿಕೆಯುಳ್ಳ ನಿರ್ಧಾರವನ್ನು ತೆಗೆದುಕೊಳ್ಳಬೇಕಾಗುತ್ತದೆ.

ಒಳಿತು ಮತ್ತು ಬಾಧಕ

ಪ್ರಸ್ತಾವಿತ ತಂತ್ರಜ್ಞಾನದ ಸಾಧಕ-ಬಾಧಕಗಳ ಮೇಲೆ ನಾನು ವಾಸಿಸಲು ಬಯಸುತ್ತೇನೆ.

ಪ್ರಯೋಜನಗಳು

ಕಂಪೈಲ್ಡ್ ಡಿಸ್ಟ್ರಿಬ್ಯೂಟ್ ಸಿಸ್ಟಮ್ ಕಾನ್ಫಿಗರೇಶನ್‌ನ ಮುಖ್ಯ ಲಕ್ಷಣಗಳ ಪಟ್ಟಿಯನ್ನು ಕೆಳಗೆ ನೀಡಲಾಗಿದೆ:

  1. ಸ್ಥಾಯೀ ಸಂರಚನಾ ಪರಿಶೀಲನೆ. ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ
    ಸಂರಚನೆ ಸರಿಯಾಗಿದೆ.
  2. ಶ್ರೀಮಂತ ಕಾನ್ಫಿಗರೇಶನ್ ಭಾಷೆ. ವಿಶಿಷ್ಟವಾಗಿ, ಇತರ ಸಂರಚನಾ ವಿಧಾನಗಳು ಸ್ಟ್ರಿಂಗ್ ವೇರಿಯಬಲ್ ಪರ್ಯಾಯಕ್ಕೆ ಸೀಮಿತವಾಗಿರುತ್ತದೆ. Scala ಅನ್ನು ಬಳಸುವಾಗ, ನಿಮ್ಮ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಸುಧಾರಿಸಲು ವ್ಯಾಪಕ ಶ್ರೇಣಿಯ ಭಾಷಾ ವೈಶಿಷ್ಟ್ಯಗಳು ಲಭ್ಯವಿವೆ. ಉದಾಹರಣೆಗೆ ನಾವು ಬಳಸಬಹುದು
    ಡೀಫಾಲ್ಟ್ ಮೌಲ್ಯಗಳ ಗುಣಲಕ್ಷಣಗಳು, ಗುಂಪು ನಿಯತಾಂಕಗಳಿಗೆ ಆಬ್ಜೆಕ್ಟ್‌ಗಳನ್ನು ಬಳಸುವುದರಿಂದ, ಸುತ್ತುವರಿದ ವ್ಯಾಪ್ತಿಯಲ್ಲಿ ಒಮ್ಮೆ ಮಾತ್ರ (DRY) ಘೋಷಿಸಲಾದ ವ್ಯಾಲ್‌ಗಳನ್ನು ನಾವು ಉಲ್ಲೇಖಿಸಬಹುದು. ನೀವು ಯಾವುದೇ ತರಗತಿಗಳನ್ನು ನೇರವಾಗಿ ಕಾನ್ಫಿಗರೇಶನ್ ಒಳಗೆ ತತ್‌ಕ್ಷಣ ಮಾಡಬಹುದು (Seq, Map, ಕಸ್ಟಮ್ ತರಗತಿಗಳು).
  3. DSL. ಸ್ಕಾಲಾ ಹಲವಾರು ಭಾಷಾ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಹೊಂದಿದ್ದು ಅದು DSL ಅನ್ನು ರಚಿಸುವುದನ್ನು ಸುಲಭಗೊಳಿಸುತ್ತದೆ. ಈ ವೈಶಿಷ್ಟ್ಯಗಳ ಲಾಭವನ್ನು ಪಡೆಯಲು ಮತ್ತು ಬಳಕೆದಾರರ ಗುರಿ ಗುಂಪಿಗೆ ಹೆಚ್ಚು ಅನುಕೂಲಕರವಾದ ಕಾನ್ಫಿಗರೇಶನ್ ಭಾಷೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಸಾಧ್ಯವಿದೆ, ಇದರಿಂದಾಗಿ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಡೊಮೇನ್ ಪರಿಣಿತರು ಓದಬಹುದು. ತಜ್ಞರು, ಉದಾಹರಣೆಗೆ, ಕಾನ್ಫಿಗರೇಶನ್ ಪರಿಶೀಲನೆ ಪ್ರಕ್ರಿಯೆಯಲ್ಲಿ ಭಾಗವಹಿಸಬಹುದು.
  4. ನೋಡ್ಗಳ ನಡುವಿನ ಸಮಗ್ರತೆ ಮತ್ತು ಸಿಂಕ್ರೊನಿ. ಸಂಪೂರ್ಣ ವಿತರಣಾ ವ್ಯವಸ್ಥೆಯ ಸಂರಚನೆಯನ್ನು ಒಂದೇ ಹಂತದಲ್ಲಿ ಸಂಗ್ರಹಿಸುವ ಒಂದು ಪ್ರಯೋಜನವೆಂದರೆ ಎಲ್ಲಾ ಮೌಲ್ಯಗಳನ್ನು ನಿಖರವಾಗಿ ಒಮ್ಮೆ ಘೋಷಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ನಂತರ ಅಗತ್ಯವಿರುವಲ್ಲೆಲ್ಲಾ ಮರುಬಳಕೆ ಮಾಡಲಾಗುತ್ತದೆ. ಪೋರ್ಟ್‌ಗಳನ್ನು ಘೋಷಿಸಲು ಫ್ಯಾಂಟಮ್ ಪ್ರಕಾರಗಳನ್ನು ಬಳಸುವುದರಿಂದ ನೋಡ್‌ಗಳು ಎಲ್ಲಾ ಸರಿಯಾದ ಸಿಸ್ಟಮ್ ಕಾನ್ಫಿಗರೇಶನ್‌ಗಳಲ್ಲಿ ಹೊಂದಾಣಿಕೆಯ ಪ್ರೋಟೋಕಾಲ್‌ಗಳನ್ನು ಬಳಸುತ್ತಿವೆ ಎಂದು ಖಚಿತಪಡಿಸುತ್ತದೆ. ನೋಡ್‌ಗಳ ನಡುವೆ ಸ್ಪಷ್ಟವಾದ ಕಡ್ಡಾಯ ಅವಲಂಬನೆಗಳನ್ನು ಹೊಂದಿರುವುದು ಎಲ್ಲಾ ಸೇವೆಗಳನ್ನು ಸಂಪರ್ಕಿಸಲಾಗಿದೆ ಎಂದು ಖಚಿತಪಡಿಸುತ್ತದೆ.
  5. ಉತ್ತಮ ಗುಣಮಟ್ಟದ ಬದಲಾವಣೆಗಳು. ಸಾಮಾನ್ಯ ಅಭಿವೃದ್ಧಿ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಬಳಸಿಕೊಂಡು ಕಾನ್ಫಿಗರೇಶನ್‌ಗೆ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡುವುದರಿಂದ ಕಾನ್ಫಿಗರೇಶನ್‌ಗೆ ಉತ್ತಮ ಗುಣಮಟ್ಟದ ಮಾನದಂಡಗಳನ್ನು ಸಾಧಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ.
  6. ಏಕಕಾಲಿಕ ಕಾನ್ಫಿಗರೇಶನ್ ನವೀಕರಣ. ಕಾನ್ಫಿಗರೇಶನ್ ಬದಲಾವಣೆಗಳ ನಂತರ ಸ್ವಯಂಚಾಲಿತ ಸಿಸ್ಟಮ್ ನಿಯೋಜನೆಯು ಎಲ್ಲಾ ನೋಡ್‌ಗಳನ್ನು ನವೀಕರಿಸಲಾಗಿದೆ ಎಂದು ಖಚಿತಪಡಿಸುತ್ತದೆ.
  7. ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸರಳಗೊಳಿಸುವುದು. ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಪಾರ್ಸಿಂಗ್, ಕಾನ್ಫಿಗರೇಶನ್ ಪರಿಶೀಲನೆ ಅಥವಾ ತಪ್ಪಾದ ಮೌಲ್ಯಗಳನ್ನು ನಿರ್ವಹಿಸುವ ಅಗತ್ಯವಿಲ್ಲ. ಇದು ಅಪ್ಲಿಕೇಶನ್‌ನ ಸಂಕೀರ್ಣತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ. (ನಮ್ಮ ಉದಾಹರಣೆಯಲ್ಲಿ ಕಂಡುಬರುವ ಕೆಲವು ಸಂರಚನಾ ಸಂಕೀರ್ಣತೆಯು ಸಂಕಲಿಸಿದ ಸಂರಚನೆಯ ಗುಣಲಕ್ಷಣವಲ್ಲ, ಆದರೆ ಹೆಚ್ಚಿನ ರೀತಿಯ ಸುರಕ್ಷತೆಯನ್ನು ಒದಗಿಸುವ ಬಯಕೆಯಿಂದ ಪ್ರಜ್ಞಾಪೂರ್ವಕ ನಿರ್ಧಾರ ಮಾತ್ರ.) ಸಾಮಾನ್ಯ ಸಂರಚನೆಗೆ ಮರಳಲು ಇದು ತುಂಬಾ ಸುಲಭ - ಕಾಣೆಯಾದದನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿ ಭಾಗಗಳು. ಆದ್ದರಿಂದ, ನೀವು, ಉದಾಹರಣೆಗೆ, ಕಂಪೈಲ್ ಮಾಡಿದ ಕಾನ್ಫಿಗರೇಶನ್‌ನೊಂದಿಗೆ ಪ್ರಾರಂಭಿಸಬಹುದು, ಅನಗತ್ಯ ಭಾಗಗಳ ಅನುಷ್ಠಾನವನ್ನು ನಿಜವಾಗಿಯೂ ಅಗತ್ಯವಿರುವ ಸಮಯದವರೆಗೆ ಮುಂದೂಡಬಹುದು.
  8. ವರ್ಸಿಫೈಡ್ ಕಾನ್ಫಿಗರೇಶನ್. ಕಾನ್ಫಿಗರೇಶನ್ ಬದಲಾವಣೆಗಳು ಯಾವುದೇ ಇತರ ಬದಲಾವಣೆಗಳ ಸಾಮಾನ್ಯ ಭವಿಷ್ಯವನ್ನು ಅನುಸರಿಸುವುದರಿಂದ, ನಾವು ಪಡೆಯುವ ಔಟ್‌ಪುಟ್ ಅನನ್ಯ ಆವೃತ್ತಿಯೊಂದಿಗೆ ಕಲಾಕೃತಿಯಾಗಿದೆ. ಅಗತ್ಯವಿದ್ದರೆ, ಕಾನ್ಫಿಗರೇಶನ್‌ನ ಹಿಂದಿನ ಆವೃತ್ತಿಗೆ ಹಿಂತಿರುಗಲು ಇದು ನಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ನಾವು ಒಂದು ವರ್ಷದ ಹಿಂದಿನ ಸಂರಚನೆಯನ್ನು ಸಹ ಬಳಸಬಹುದು ಮತ್ತು ಸಿಸ್ಟಮ್ ನಿಖರವಾಗಿ ಒಂದೇ ರೀತಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. ಸ್ಥಿರವಾದ ಸಂರಚನೆಯು ವಿತರಿಸಿದ ವ್ಯವಸ್ಥೆಯ ಭವಿಷ್ಯ ಮತ್ತು ವಿಶ್ವಾಸಾರ್ಹತೆಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ. ಸಂರಚನೆಯನ್ನು ಸಂಕಲನ ಹಂತದಲ್ಲಿ ಸರಿಪಡಿಸಲಾಗಿರುವುದರಿಂದ, ಉತ್ಪಾದನೆಯಲ್ಲಿ ಅದನ್ನು ನಕಲಿ ಮಾಡುವುದು ತುಂಬಾ ಕಷ್ಟ.
  9. ಮಾಡ್ಯುಲಾರಿಟಿ. ಪ್ರಸ್ತಾವಿತ ಚೌಕಟ್ಟು ಮಾಡ್ಯುಲರ್ ಆಗಿದೆ ಮತ್ತು ವಿಭಿನ್ನ ವ್ಯವಸ್ಥೆಗಳನ್ನು ರಚಿಸಲು ಮಾಡ್ಯೂಲ್‌ಗಳನ್ನು ವಿಭಿನ್ನ ರೀತಿಯಲ್ಲಿ ಸಂಯೋಜಿಸಬಹುದು. ನಿರ್ದಿಷ್ಟವಾಗಿ, ನೀವು ಒಂದು ಸಾಕಾರದಲ್ಲಿ ಒಂದೇ ನೋಡ್‌ನಲ್ಲಿ ಮತ್ತು ಇನ್ನೊಂದರಲ್ಲಿ ಬಹು ನೋಡ್‌ಗಳಲ್ಲಿ ಚಲಾಯಿಸಲು ಸಿಸ್ಟಮ್ ಅನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಬಹುದು. ಸಿಸ್ಟಮ್ನ ಉತ್ಪಾದನಾ ನಿದರ್ಶನಗಳಿಗಾಗಿ ನೀವು ಹಲವಾರು ಸಂರಚನೆಗಳನ್ನು ರಚಿಸಬಹುದು.
  10. ಪರೀಕ್ಷೆ. ಮಾಕ್ ಆಬ್ಜೆಕ್ಟ್ಗಳೊಂದಿಗೆ ಪ್ರತ್ಯೇಕ ಸೇವೆಗಳನ್ನು ಬದಲಿಸುವ ಮೂಲಕ, ಪರೀಕ್ಷೆಗೆ ಅನುಕೂಲಕರವಾದ ಸಿಸ್ಟಮ್ನ ಹಲವಾರು ಆವೃತ್ತಿಗಳನ್ನು ನೀವು ಪಡೆಯಬಹುದು.
  11. ಏಕೀಕರಣ ಪರೀಕ್ಷೆ. ಸಂಪೂರ್ಣ ವಿತರಣಾ ವ್ಯವಸ್ಥೆಗೆ ಒಂದೇ ಸಂರಚನೆಯನ್ನು ಹೊಂದುವುದರಿಂದ ಏಕೀಕರಣ ಪರೀಕ್ಷೆಯ ಭಾಗವಾಗಿ ನಿಯಂತ್ರಿತ ಪರಿಸರದಲ್ಲಿ ಎಲ್ಲಾ ಘಟಕಗಳನ್ನು ಚಲಾಯಿಸಲು ಸಾಧ್ಯವಾಗಿಸುತ್ತದೆ. ಅನುಕರಿಸುವುದು ಸುಲಭ, ಉದಾಹರಣೆಗೆ, ಕೆಲವು ನೋಡ್‌ಗಳು ಪ್ರವೇಶಿಸಬಹುದಾದ ಪರಿಸ್ಥಿತಿ.

ಅನಾನುಕೂಲಗಳು ಮತ್ತು ಮಿತಿಗಳು

ಸಂಕಲಿಸಿದ ಸಂರಚನೆಯು ಇತರ ಸಂರಚನಾ ವಿಧಾನಗಳಿಂದ ಭಿನ್ನವಾಗಿದೆ ಮತ್ತು ಕೆಲವು ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ ಸೂಕ್ತವಾಗಿರುವುದಿಲ್ಲ. ಕೆಳಗೆ ಕೆಲವು ಅನಾನುಕೂಲಗಳು:

  1. ಸ್ಥಿರ ಸಂರಚನೆ. ಕೆಲವೊಮ್ಮೆ ನೀವು ಎಲ್ಲಾ ರಕ್ಷಣಾತ್ಮಕ ಕಾರ್ಯವಿಧಾನಗಳನ್ನು ಬೈಪಾಸ್ ಮಾಡುವ ಮೂಲಕ ಉತ್ಪಾದನೆಯಲ್ಲಿನ ಸಂರಚನೆಯನ್ನು ತ್ವರಿತವಾಗಿ ಸರಿಪಡಿಸಬೇಕಾಗಿದೆ. ಈ ವಿಧಾನದಿಂದ ಇದು ಹೆಚ್ಚು ಕಷ್ಟಕರವಾಗಿರುತ್ತದೆ. ಕನಿಷ್ಠ, ಸಂಕಲನ ಮತ್ತು ಸ್ವಯಂಚಾಲಿತ ನಿಯೋಜನೆ ಇನ್ನೂ ಅಗತ್ಯವಿದೆ. ಇದು ವಿಧಾನದ ಉಪಯುಕ್ತ ಲಕ್ಷಣವಾಗಿದೆ ಮತ್ತು ಕೆಲವು ಸಂದರ್ಭಗಳಲ್ಲಿ ಅನನುಕೂಲವಾಗಿದೆ.
  2. ಕಾನ್ಫಿಗರೇಶನ್ ಉತ್ಪಾದನೆ. ಒಂದು ವೇಳೆ ಕಾನ್ಫಿಗರೇಶನ್ ಫೈಲ್ ಅನ್ನು ಸ್ವಯಂಚಾಲಿತ ಉಪಕರಣದಿಂದ ರಚಿಸಿದರೆ, ಬಿಲ್ಡ್ ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಸಂಯೋಜಿಸಲು ಹೆಚ್ಚುವರಿ ಪ್ರಯತ್ನಗಳು ಬೇಕಾಗಬಹುದು.
  3. ಪರಿಕರಗಳು. ಪ್ರಸ್ತುತ, ಸಂರಚನೆಯೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಲು ವಿನ್ಯಾಸಗೊಳಿಸಲಾದ ಉಪಯುಕ್ತತೆಗಳು ಮತ್ತು ತಂತ್ರಗಳು ಪಠ್ಯ ಫೈಲ್‌ಗಳನ್ನು ಆಧರಿಸಿವೆ. ಕಂಪೈಲ್ ಮಾಡಿದ ಕಾನ್ಫಿಗರೇಶನ್‌ನಲ್ಲಿ ಅಂತಹ ಎಲ್ಲಾ ಉಪಯುಕ್ತತೆಗಳು/ತಂತ್ರಗಳು ಲಭ್ಯವಿರುವುದಿಲ್ಲ.
  4. ವರ್ತನೆಗಳಲ್ಲಿ ಬದಲಾವಣೆ ಅಗತ್ಯ. ಡೆವಲಪರ್‌ಗಳು ಮತ್ತು DevOps ಪಠ್ಯ ಫೈಲ್‌ಗಳಿಗೆ ಒಗ್ಗಿಕೊಂಡಿರುತ್ತಾರೆ. ಸಂರಚನೆಯನ್ನು ಕಂಪೈಲ್ ಮಾಡುವ ಕಲ್ಪನೆಯು ಸ್ವಲ್ಪಮಟ್ಟಿಗೆ ಅನಿರೀಕ್ಷಿತ ಮತ್ತು ಅಸಾಮಾನ್ಯ ಮತ್ತು ನಿರಾಕರಣೆಗೆ ಕಾರಣವಾಗಬಹುದು.
  5. ಉತ್ತಮ ಗುಣಮಟ್ಟದ ಅಭಿವೃದ್ಧಿ ಪ್ರಕ್ರಿಯೆಯ ಅಗತ್ಯವಿದೆ. ಕಂಪೈಲ್ ಮಾಡಿದ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಆರಾಮದಾಯಕವಾಗಿ ಬಳಸಲು, ಅಪ್ಲಿಕೇಶನ್ (CI/CD) ಅನ್ನು ನಿರ್ಮಿಸುವ ಮತ್ತು ನಿಯೋಜಿಸುವ ಪ್ರಕ್ರಿಯೆಯ ಸಂಪೂರ್ಣ ಯಾಂತ್ರೀಕೃತಗೊಂಡ ಅಗತ್ಯವಿರುತ್ತದೆ. ಇಲ್ಲದಿದ್ದರೆ ಅದು ಸಾಕಷ್ಟು ಅನಾನುಕೂಲವಾಗುತ್ತದೆ.

ಸಂಕಲಿಸಿದ ಸಂರಚನೆಯ ಕಲ್ಪನೆಗೆ ಸಂಬಂಧಿಸದ ಪರಿಗಣಿಸಲಾದ ಉದಾಹರಣೆಯ ಹಲವಾರು ಮಿತಿಗಳ ಮೇಲೆ ನಾವು ವಾಸಿಸೋಣ:

  1. ನೋಡ್‌ನಿಂದ ಬಳಸದ ಅನಗತ್ಯ ಕಾನ್ಫಿಗರೇಶನ್ ಮಾಹಿತಿಯನ್ನು ನಾವು ಒದಗಿಸಿದರೆ, ಕಾಣೆಯಾದ ಅನುಷ್ಠಾನವನ್ನು ಪತ್ತೆಹಚ್ಚಲು ಕಂಪೈಲರ್ ನಮಗೆ ಸಹಾಯ ಮಾಡುವುದಿಲ್ಲ. ಕೇಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ತ್ಯಜಿಸುವ ಮೂಲಕ ಮತ್ತು ಹೆಚ್ಚು ಕಟ್ಟುನಿಟ್ಟಾದ ಪ್ರಕಾರಗಳನ್ನು ಬಳಸುವ ಮೂಲಕ ಈ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಬಹುದು, ಉದಾಹರಣೆಗೆ, HList ಅಥವಾ ಸಂರಚನೆಯನ್ನು ಪ್ರತಿನಿಧಿಸಲು ಬೀಜಗಣಿತದ ಡೇಟಾ ಪ್ರಕಾರಗಳು (ಕೇಸ್ ವರ್ಗಗಳು).
  2. ಕಾನ್ಫಿಗರೇಶನ್ ಫೈಲ್‌ನಲ್ಲಿ ಕಾನ್ಫಿಗರೇಶನ್‌ಗೆ ಸಂಬಂಧಿಸದ ಸಾಲುಗಳಿವೆ: (package, import,ಆಬ್ಜೆಕ್ಟ್ ಘೋಷಣೆಗಳು; override defಡೀಫಾಲ್ಟ್ ಮೌಲ್ಯಗಳನ್ನು ಹೊಂದಿರುವ ನಿಯತಾಂಕಗಳಿಗಾಗಿ). ನಿಮ್ಮ ಸ್ವಂತ DSL ಅನ್ನು ನೀವು ಅಳವಡಿಸಿಕೊಂಡರೆ ಇದನ್ನು ಭಾಗಶಃ ತಪ್ಪಿಸಬಹುದು. ಹೆಚ್ಚುವರಿಯಾಗಿ, ಇತರ ರೀತಿಯ ಸಂರಚನೆಗಳು (ಉದಾಹರಣೆಗೆ, XML) ಫೈಲ್ ರಚನೆಯ ಮೇಲೆ ಕೆಲವು ನಿರ್ಬಂಧಗಳನ್ನು ವಿಧಿಸುತ್ತವೆ.
  3. ಈ ಪೋಸ್ಟ್‌ನ ಉದ್ದೇಶಗಳಿಗಾಗಿ, ಒಂದೇ ರೀತಿಯ ನೋಡ್‌ಗಳ ಕ್ಲಸ್ಟರ್‌ನ ಡೈನಾಮಿಕ್ ಮರುಸಂರಚನೆಯನ್ನು ನಾವು ಪರಿಗಣಿಸುತ್ತಿಲ್ಲ.

ತೀರ್ಮಾನಕ್ಕೆ

ಈ ಪೋಸ್ಟ್‌ನಲ್ಲಿ, ಸ್ಕಾಲಾ ಪ್ರಕಾರದ ವ್ಯವಸ್ಥೆಯ ಸುಧಾರಿತ ಸಾಮರ್ಥ್ಯಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಮೂಲ ಕೋಡ್‌ನಲ್ಲಿ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಪ್ರತಿನಿಧಿಸುವ ಕಲ್ಪನೆಯನ್ನು ನಾವು ಅನ್ವೇಷಿಸಿದ್ದೇವೆ. ಈ ವಿಧಾನವನ್ನು xml ಅಥವಾ ಪಠ್ಯ ಫೈಲ್‌ಗಳ ಆಧಾರದ ಮೇಲೆ ಸಾಂಪ್ರದಾಯಿಕ ಸಂರಚನಾ ವಿಧಾನಗಳಿಗೆ ಬದಲಿಯಾಗಿ ವಿವಿಧ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಲ್ಲಿ ಬಳಸಬಹುದು. ನಮ್ಮ ಉದಾಹರಣೆಯನ್ನು ಸ್ಕಾಲಾದಲ್ಲಿ ಅಳವಡಿಸಲಾಗಿದ್ದರೂ ಸಹ, ಅದೇ ಆಲೋಚನೆಗಳನ್ನು ಇತರ ಸಂಕಲನ ಭಾಷೆಗಳಿಗೆ ವರ್ಗಾಯಿಸಬಹುದು (ಉದಾಹರಣೆಗೆ ಕೋಟ್ಲಿನ್, ಸಿ #, ಸ್ವಿಫ್ಟ್, ...). ಕೆಳಗಿನ ಯೋಜನೆಗಳಲ್ಲಿ ಒಂದನ್ನು ನೀವು ಈ ವಿಧಾನವನ್ನು ಪ್ರಯತ್ನಿಸಬಹುದು, ಮತ್ತು ಅದು ಕಾರ್ಯನಿರ್ವಹಿಸದಿದ್ದರೆ, ಪಠ್ಯ ಫೈಲ್‌ಗೆ ತೆರಳಿ, ಕಾಣೆಯಾದ ಭಾಗಗಳನ್ನು ಸೇರಿಸಿ.

ಸ್ವಾಭಾವಿಕವಾಗಿ, ಸಂಕಲಿಸಿದ ಸಂರಚನೆಗೆ ಉತ್ತಮ ಗುಣಮಟ್ಟದ ಅಭಿವೃದ್ಧಿ ಪ್ರಕ್ರಿಯೆಯ ಅಗತ್ಯವಿದೆ. ಪ್ರತಿಯಾಗಿ, ಕಾನ್ಫಿಗರೇಶನ್‌ಗಳ ಉತ್ತಮ ಗುಣಮಟ್ಟ ಮತ್ತು ವಿಶ್ವಾಸಾರ್ಹತೆಯನ್ನು ಖಾತ್ರಿಪಡಿಸಲಾಗಿದೆ.

ಪರಿಗಣಿಸಲಾದ ವಿಧಾನವನ್ನು ವಿಸ್ತರಿಸಬಹುದು:

  1. ಕಂಪೈಲ್-ಟೈಮ್ ಚೆಕ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಲು ನೀವು ಮ್ಯಾಕ್ರೋಗಳನ್ನು ಬಳಸಬಹುದು.
  2. ಅಂತಿಮ ಬಳಕೆದಾರರಿಗೆ ಪ್ರವೇಶಿಸಬಹುದಾದ ರೀತಿಯಲ್ಲಿ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಪ್ರಸ್ತುತಪಡಿಸಲು ನೀವು DSL ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಬಹುದು.
  3. ಸ್ವಯಂಚಾಲಿತ ಸಂರಚನಾ ಹೊಂದಾಣಿಕೆಯೊಂದಿಗೆ ನೀವು ಡೈನಾಮಿಕ್ ಸಂಪನ್ಮೂಲ ನಿರ್ವಹಣೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಬಹುದು. ಉದಾಹರಣೆಗೆ, ಒಂದು ಕ್ಲಸ್ಟರ್‌ನಲ್ಲಿ ನೋಡ್‌ಗಳ ಸಂಖ್ಯೆಯನ್ನು ಬದಲಾಯಿಸಲು (1) ಪ್ರತಿ ನೋಡ್ ಸ್ವಲ್ಪ ವಿಭಿನ್ನವಾದ ಸಂರಚನೆಯನ್ನು ಪಡೆಯುವುದು ಅವಶ್ಯಕ; (2) ಕ್ಲಸ್ಟರ್ ಮ್ಯಾನೇಜರ್ ಹೊಸ ನೋಡ್‌ಗಳ ಬಗ್ಗೆ ಮಾಹಿತಿಯನ್ನು ಪಡೆದರು.

ಸ್ವೀಕೃತಿಗಳು

ಕರಡು ಲೇಖನದ ರಚನಾತ್ಮಕ ಟೀಕೆಗಾಗಿ ನಾನು ಆಂಡ್ರೇ ಸಕ್ಸೊನೊವ್, ಪಾವೆಲ್ ಪೊಪೊವ್ ಮತ್ತು ಆಂಟನ್ ನೆಖೇವ್ ಅವರಿಗೆ ಧನ್ಯವಾದ ಹೇಳಲು ಬಯಸುತ್ತೇನೆ.

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ